iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >go GCM gin中间件怎么加密解密文件
  • 696
分享到

go GCM gin中间件怎么加密解密文件

2023-06-30 14:06:24 696人浏览 薄情痞子
摘要

这篇文章主要介绍“Go GCM gin中间件怎么加密解密文件”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“go GCM gin中间件怎么加密解密文件”文章能帮

这篇文章主要介绍“Go GCM gin中间件怎么加密解密文件”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“go GCM gin中间件怎么加密解密文件”文章能帮助大家解决问题。

aes的gcm模式的加密和解密

要给已有的系统启用加密解密,目前推荐的是aes的gcm模式的加密和解密,在微服务如果向前有公共方法处理 读取数据和写返回数据,那么比较简单,修改以前的公共方法,但是这样本地调试平时肯定是明文,所以要加判断,如果以前的读数据和写数据是五花八门那就比较麻烦,在微服务体系里面一般有网关这个服务,所以加密和解密就放在网关服务,大致如下:

go GCM gin中间件怎么加密解密文件

常规的请求有GET,POST JSON, POST file,以及POST FORM表单,返回一般是json 或者下载文件流,所以我们需要截获请求流和返回流,收到请求流解密数据 然后重新写入到请求流,收到返回流加密数据,重写返回流。

首先来看aes加密和解密程序aes.go

package aesimport ("crypto/aes""crypto/cipher""crypto/md5""crypto/rand""encoding/base64""encoding/hex""errors""io")//加密字符串func GcmEncrypt(key, plaintext string) (string, error) {if len(key) != 32 && len(key) != 24 && len(key) != 16 {return "", errors.New("the length of key is error")}if len(plaintext) < 1 {return "", errors.New("plaintext is null")}keyByte := []byte(key)plainByte:=[]byte(plaintext)block, err := aes.NewCipher(keyByte)if err != nil {return "", err}aesGcm, err := cipher.NewGCM(block)if err != nil {return "", err}nonce := make([]byte, 12)if _, err := io.ReadFull(rand.Reader, nonce); err != nil {return "", err}seal := aesGcm.Seal(nonce, nonce, plainByte, nil)return base64.URLEncoding.EncodeToString(seal), nil}//解密字符串func GcmDecrypt(key, cipherText string) (string, error) {if len(key) != 32 && len(key) != 24 && len(key) != 16 {return "", errors.New("the length of key is error")}if len(cipherText) < 1 {return "", errors.New("cipherText is null")}cipherByte, err := base64.URLEncoding.DecodeString(cipherText)if err != nil {return "", err}if len(cipherByte) < 12 {return "", errors.New("cipherByte is error")}nonce, cipherByte := cipherByte[:12], cipherByte[12:]keyByte := []byte(key)block, err := aes.NewCipher(keyByte)if err != nil {return "", err}aesGcm, err := cipher.NewGCM(block)if err != nil {return "", err}plainByte, err := aesGcm.Open(nil, nonce, cipherByte, nil)if err != nil {return "", err}return string(plainByte), nil}//生成32位md5字串func GetAesKey(s string) string {h := md5.New()h.Write([]byte(s))return hex.EncodeToString(h.Sum(nil))}

再来看看网关转发程序proxy.go

package middlewareimport ("fmt""GitHub.com/gin-gonic/gin""github.com/valyala/fastHttp""io/ioutil""runtime/debug""time")var fastClient *fasthttp.Clientfunc init() {fastClient = &fasthttp.Client{}fastClient.MaxIdemponentCallAttempts = 1fastClient.ReadTimeout = time.Second * 60}func GetHttpClient() *fasthttp.Client {return fastClient}func GateWay() gin.HandlerFunc {return func(c *gin.Context) {defer func() {if e := recover(); e != nil {stack := debug.Stack()log("GateWay Recovery: err:%v, stack:%v", e, string(stack))}}()err := Forward(c)if err != nil {response(c, 9999, "系统错误", err.Error())}return}}func Forward(ctx *gin.Context) error {req := &fasthttp.Request{}//请求-获取服务地址host := "http://localhost:8000/" + ctx.Request.URL.String()//请求-urlreq.SetRequestURI(host)//请求-headerfor k, v := range ctx.Request.Header {req.Header.Set(k, v[0])}//请求-bodydata, err := ioutil.ReadAll(ctx.Request.Body)if err != nil {log("Forward err:%v", err)return fmt.Errorf("系统错误")}req.SetBody(data)//请求-方法req.Header.SetMethod(ctx.Request.Method)//请求-发送resp := &fasthttp.Response{}//请求-新增调用链err = GetHttpClient().Do(req, resp)if err != nil {log("Forward GetHttpClient DO err:%v", err)return fmt.Errorf("系统错误")}//请求-响应ContentType := fmt.Sprintf("%s", resp.Header.Peek("Content-Type"))ctx.Data(resp.StatusCode(), ContentType, resp.Body())return nil}type HTTPHeadersCarrier struct {*fasthttp.RequestHeader}func (c HTTPHeadersCarrier) Set(key, val string) {h := c.RequestHeaderh.Add(key, val)}

最后来看一下gin的中间件crypto.go

package middlewareimport ("bytes""demo/aes""encoding/json""errors""fmt""github.com/gin-gonic/gin""io""io/ioutil""mime""mime/multipart""net/url""runtime/debug""strconv""strings")type aesWriter struct {gin.ResponseWriterbody *bytes.Buffer}func (w *aesWriter) Write(b []byte) (int, error) {return w.body.Write(b)}func (w *aesWriter) WriteString(s string) (int, error) {return w.body.WriteString(s)}//只有经过token 验证的才会加密 和解密//handleFile 表示是否处理上传文件, 默认网关不处理上传文件的encryptString数据, 如果处理会导致具体服务无法接收到具体参数func AesGcmDecrypt() gin.HandlerFunc {return func(c *gin.Context) {defer func() {if e := recover(); e != nil {stack := debug.Stack()log("AesGcmDecrypt Recovery: err:%v, stack:%v", e, string(stack))}}()if c.Request.Method == "OPTIONS" {c.Next()} else {md5key := aes.GetAesKey("gavin12345678")log("AesGcmDecrypt start url:%s  ,md5key:%s, Method:%s, Header:%+v", c.Request.URL.String(), md5key, c.Request.Method, c.Request.Header)handleAes(c, md5key)}}}//请求和返回都加密 解密func handleAes(c *gin.Context, md5key string) {contentType := c.Request.Header.Get("Content-Type")isJsonRequest := strings.Contains(contentType, "application/json")isFileRequest := strings.Contains(contentType, "multipart/form-data")isFormUrl := strings.Contains(contentType, "application/x-www-form-urlencoded")if c.Request.Method == "GET" {err := parseQuery(c, md5key)if err != nil {log("handleAes parseQuery  err:%v", err)//这里输出应该密文 一旦加密解密调试好 这里就不会走进来response(c, 2001, "系统错误", err.Error())return}} else if isJsonRequest {err := parseJson(c, md5key)if err != nil {log("handleAes parseJson err:%v", err)//这里输出应该密文 一旦加密解密调试好 这里就不会走进来response(c, 2001, "系统错误", err.Error())return}} else if isFormUrl {err := parseForm(c, md5key)if err != nil {log("handleAes parseForm err:%v", err)//这里输出应该密文 一旦加密解密调试好 这里就不会走进来response(c, 2001, "系统错误", err.Error())return}} else if isFileRequest {err := parseFile(c, md5key)if err != nil {log("handleAes parseFile err:%v", err)//这里输出应该密文 一旦加密解密调试好 这里就不会走进来response(c, 2001, "系统错误", err.Error())return}}///截取 response bodyoldWriter := c.Writerblw := &aesWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}c.Writer = blw// 走流程c.Next()///获取返回数据responseByte := blw.body.Bytes()//日志c.Writer = oldWriter//如果返回的不是json格式 那么直接返回,应为文件下载之类的不应该加密if !isJsonResponse(c) {_, _ = c.Writer.Write(responseByte)return}///加密encryptStr, err := aes.GcmEncrypt(md5key, string(responseByte))if err != nil {log("handleAes GcmEncrypt err:%v", err)response(c, 2001, "系统错误", err.Error())return}_, _ = c.Writer.WriteString(encryptStr)}//处理jsonfunc parseJson(c *gin.Context, md5key string) error {//读取数据 body处理payload, err := c.GetRawData()if err != nil {return err}///解密body数据 请求的json是{"encryptString":{value}} value含有gcm的12字节nonce,实际长度大于32if payload != nil && len(payload) > 20 {var jsonData encryptJsonlog("AesGcmDecrypt  parseJson url:%s md5key:%s,old data:%s,", c.Request.URL.String(), md5key, string(payload))err := json.Unmarshal(payload, &jsonData)if err != nil {log("AesGcmDecrypt parseJson Unmarshal err:%v", err)return err}payloadText := jsonData.EncryptStringif len(payloadText) > 0 {payloadText, err = aes.GcmDecrypt(md5key, payloadText)if err != nil {log("AesGcmDecrypt parseJson GcmDecryptByte err:%v", err)return err}payload = []byte(payloadText)log("AesGcmDecrypt  parseJson url:%s md5key:%s,encryptString:%s,decrypt data:%s", c.Request.URL.String(), md5key, jsonData.EncryptString, payloadText)}}c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(payload))return nil}func parseForm(c *gin.Context, md5key string) error {//读取数据 body处理payload, err := c.GetRawData()if err != nil {return err}///解密body数据 请求的json是"encryptString= value含有gcm的12字节nonce,实际长度大于32if payload != nil && len(payload) > 20 {var jsonData encryptJsonlog("AesGcmDecrypt  parseForm url:%s md5key:%s,old data:%s,", c.Request.URL.String(), md5key, string(payload))values, err := url.ParseQuery(string(payload))if err != nil {log("AesGcmDecrypt parseForm ParseQuery err:%v", err)return err}payloadText := values.Get("encryptString")if len(payloadText) > 0 {mapData, err := gcmDecryptString(md5key, payloadText)if err != nil {log("AesGcmDecrypt parseForm gcmDecryptString err:%v", err)return err}for k, v := range mapData {values.Add(k, getStr(v))}formData := values.Encode()log("AesGcmDecrypt  parseForm url:%s md5key:%s,encryptString:%s,decrypt data:%s", c.Request.URL.String(), md5key, jsonData.EncryptString, formData)payload = []byte(formData)}}c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(payload))return nil}//处理get url的解密func parseQuery(c *gin.Context, md5Key string) error {encryptString := c.Query("encryptString")log("AesGcmDecrypt parseQuery url:%s, md5key:%s, encryptString:%s", c.Request.URL.String(), md5Key, encryptString)if len(encryptString) < 1 {return nil}queryData, err := gcmDecryptString(md5Key, encryptString)if err != nil {return err}var args []stringvar logs []stringfor k, v := range queryData {val := getStr(v)args = append(args, fmt.Sprintf("%s=%s", k, url.QueryEscape(val)))logs = append(logs, fmt.Sprintf("%s=%s", k, val))}log("AesGcmDecrypt parseQuery  url:%s, md5key:%s, encryptString:%s, decrypt data:%s", c.Request.URL.String(), md5Key, encryptString, strings.Join(logs, "&"))c.Request.URL.RawQuery = strings.Join(args, "&")return nil}func parseFile(c *gin.Context, md5Key string) error {contentType := c.Request.Header.Get("Content-Type")_, params, _ := mime.ParseMediaType(contentType)boundary, ok := params["boundary"]if !ok {return errors.New("no multipart boundary param in Content-Type")}//准备重写数据bodyBuf := &bytes.Buffer{}wr := multipart.NewWriter(bodyBuf)mr := multipart.NewReader(c.Request.Body, boundary)for {p, err := mr.NextPart() //p的类型为Partif err == io.EOF {break}if err != nil {log("NextPart err:%v", err)break}fileByte, err := ioutil.ReadAll(p)if err != nil {log("ReadAll err:%v", err)break}pName := p.FormName()fileName := p.FileName()if len(fileName) < 1 {if pName == "encryptString" {formData, err := gcmDecryptString(md5Key, string(fileByte))if err != nil {log("AesGcmDecrypt writeFile gcmDecryptString err:%v", err)break}for k, v := range formData {val := getStr(v)err = wr.WriteField(k, val)if err != nil {log("AesGcmDecrypt writeFile WriteField :%s=%s, err:%v", k, val, err)break}}} else {wr.WriteField(pName, string(fileByte))}} else {tmp, err := wr.CreateFormFile(pName, fileName)if err != nil {log("AesGcmDecrypt parseFile CreateFormFile err:%v", err)continue}tmp.Write(fileByte)}}//写结尾标志_ = wr.Close()c.Request.Header.Set("Content-Type", wr.FormDataContentType())c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBuf.Bytes()))return nil}func gcmDecryptString(md5Key, encryptString string) (map[string]interface{}, error) {formData := make(map[string]interface{}, 0)if len(encryptString) < 1 {return formData, nil}plaintext, err := aes.GcmDecrypt(md5Key, encryptString)if err != nil {return formData, err}if len(plaintext) < 3 {//plaintext 应该是json 串 {}return formData, nil}err = json.Unmarshal([]byte(plaintext), &formData)if err != nil {return formData, err}return formData, nil}func isJsonResponse(c *gin.Context) bool {contentType := c.Writer.Header().Get("Content-Type")return strings.Contains(contentType, "application/json")}func getStr(v interface{}) string {val := ""switch v.(type) {case float64://tmp, _ := decimal.NewFromString(fmt.Sprintf("%.10f", v))fl, _ := v.(float64)val = strconv.FormatFloat(fl, 'f', -1, 64)default:val = fmt.Sprintf("%v", v)}return val}type encryptJson struct {EncryptString string `json:"encryptString"`}func log(format string, arg ...interface{}) {fmt.Print(fmt.Sprintf(format, arg...))}func response(c *gin.Context, code int, msg string, data interface{}) {mapData := make(map[string]interface{}, 0)mapData["code"] = codemapData["msg"] = msgmapData["data"] = datac.JSON(200, data)c.Abort()return}

最后我们来写一个demo程序main.go

package mainimport ("demo/middleware""fmt""github.com/gin-gonic/gin""os")func main() {go func() {gateway := gin.Default()gateway.Use(middleware.AesGcmDecrypt())gateway.Use(middleware.GateWay())gateway.Run(":8080")}()// 1.创建路由r := gin.Default()r.Use(middleware.Logger())r.GET("/", func(c *gin.Context) {c.Writer.WriteString("pong")})r.GET("/demo", func(c *gin.Context) {req := ReqObj{}err := c.ShouldBindQuery(&req)if err != nil {fmt.Print(err)}response(c, 200, "ok", req)})r.POST("/test", func(c *gin.Context) {req := ReqObj{}err := c.ShouldBind(&req)if err != nil {fmt.Print(err)}response(c, 200, "ok", req)})r.POST("/form", func(c *gin.Context) {req := ReqObj{}err := c.ShouldBind(&req)if err != nil {fmt.Print(err)}response(c, 200, "ok", req)})r.POST("/upload", func(c *gin.Context) {file, err := c.FormFile("file")if err != nil {fmt.Print(err)}folder := c.Request.FormValue("folder")tmp, _ := os.Getwd()filePath := tmp + "/upload/" + folder + "/" + file.Filenamec.SaveUploadedFile(file, filePath)})r.Run(":8000")}type ReqObj struct {Name       string `json:"name" form:"name"`Age        int64  `json:"age"  form:"age"`UpdateTime int64  `json:"update_time"  form:"update_time"`Folder     string `json:"folder"  form:"folder"`}func response(c *gin.Context, code int, msg string, data interface{}) {mapData := make(map[string]interface{}, 0)mapData["code"] = codemapData["msg"] = msgmapData["data"] = datac.JSON(200, data)c.Abort()return}

验证

来让我们一次验证一下运行结果:

1.GET请求

go GCM gin中间件怎么加密解密文件

2.看看post json

go GCM gin中间件怎么加密解密文件

3验证postform

go GCM gin中间件怎么加密解密文件

最后来看一下文件上传:

go GCM gin中间件怎么加密解密文件

关于“go GCM gin中间件怎么加密解密文件”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网精选频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: go GCM gin中间件怎么加密解密文件

本文链接: https://www.lsjlt.com/news/329740.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • go GCM gin中间件怎么加密解密文件
    这篇文章主要介绍“go GCM gin中间件怎么加密解密文件”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“go GCM gin中间件怎么加密解密文件”文章能帮...
    99+
    2023-06-30
  • go GCM gin中间件的加密解密文件流处理
    目录aes的gcm模式的加密和解密验证1.GET请求2.看看post json3验证postformaes的gcm模式的加密和解密 要给已有的系统启用加密解密,目前推荐的是aes的g...
    99+
    2024-04-02
  • c++文件怎么加密和解密
    加密和解密C++文件可以通过使用加密算法和解密算法来实现。以下是一个简单的示例代码,用于对文件进行加密和解密操作: #include...
    99+
    2024-04-08
    c++
  • PHP sm4国密加密解密文件
    phpsm2sm3sm4: php 国密算法 支持 m2 sm3 sm4 SM3WithSM2签名 来源地址:https://blog.csdn.net/licanfeng1/article/details/132236052...
    99+
    2023-09-06
    android android studio ide php
  • 怎么破解加密zip文件的密码
    本篇内容主要讲解“怎么破解加密zip文件的密码”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么破解加密zip文件的密码”吧!之前在家里的老电脑中,发现一个加密zip压缩包,由于时隔太久忘记密码...
    99+
    2023-06-15
  • java怎么实现rsa加密解密文件
    要在Java中实现RSA加密和解密文件,可以使用Java Cryptography Architecture(JCA)提供的RSA算...
    99+
    2023-10-26
    java
  • PHP中怎么破解 Zend加密文件
    这篇文章将为大家详细讲解有关PHP中怎么破解 Zend加密文件,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。PHP Zend加密文件破解相关代码:function send_con...
    99+
    2023-06-17
  • Python中怎么破解加密zip文件
    Python中怎么破解加密zip文件,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Python有一个内置模块zipfile可以干这个事情,测试一波,一个测试文件,设置解压密...
    99+
    2023-06-15
  • python怎么加密文件
    使用python加密文件的方法:1.新建python项目;2.导入hashlib模块;3.使用hashlib.sha1()方法加密内容;4.使用open()函数打开文件;5.使用write()方法将内容写入文件;具体步骤如下:首先,打开py...
    99+
    2024-04-02
  • php文件怎么加密
    这篇文章将为大家详细讲解有关php文件怎么加密,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。php文件加密的方法:1、打开Zend Guard 5.5.0;2、选择要进行加密的源文件或文件夹;3、选择PH...
    99+
    2023-06-20
  • Android怎么加密文件
    在Android设备上,您可以使用以下方法来加密文件:1. 使用应用程序:您可以使用加密文件管理应用程序,例如ES文件资源管理器或Solid Explorer等应用程序。这些应用程序通常提供加密和解密文件的功能。您可以选择要加密的文件,...
    99+
    2023-08-11
    Android
  • c语言中的文件加密与解密
    目录c语言文件加密与解密具体加密过程如下解密过程与加密过程类似,采用的是模26减运算功能要求系统应提供以下功能总结c语言文件加密与解密 本程序是一个c语言的大作业的一部分 是简单的基...
    99+
    2023-05-18
    c语言文件加密 c语言文件解密 c文件加密与解密
  • Vim怎么给文件加密
    这篇文章主要介绍“Vim怎么给文件加密”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vim怎么给文件加密”文章能帮助大家解决问题。怎样在 Linux 中用 Vim 对文件进行密码保护Vim 有个 -...
    99+
    2023-06-27
  • Linux系统中怎么加密文件
    这篇文章主要讲解了“Linux系统中怎么加密文件”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux系统中怎么加密文件”吧!在Linux系统安装时选择使用EFS首先将介绍一个非常简单的方...
    99+
    2023-06-17
  • xp怎么给文件加密
    今天小编给大家分享一下xp怎么给文件加密的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。xp如何给文件加密鼠标右键选择要加密的...
    99+
    2023-06-27
  • Linux下怎么加密文件
    本篇内容主要讲解“Linux下怎么加密文件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linux下怎么加密文件”吧!Linux文件加密具体方法方法一:gzexe加密 这种加密方式不是非常保险的...
    99+
    2023-06-28
  • win10怎么加密文件夹
    使用win10系统的小伙伴肯定不在少数吧,你们会不会有想要进行加密的文件夹呢那你们又知不知道win10加密文件夹在哪设置呢如果不知道的话接下来小编就来告诉大家win10怎么加密文件夹,有需要的小伙伴一起往下看看吧。1、首先我们在电脑上打开文...
    99+
    2023-07-12
  • go语言gin框架中间件详解
    目录1、gin框架限流中间件2、gin框架跨域中间件 3、gin框架数据库中间件4、gin框架redis中间件5、gin框架es中间件6、gin框架rabbitMQ中间件7...
    99+
    2023-05-16
    go语言gin框架中间件 gin框架中间件 go gin框架中间件 go 中间件
  • 详解C#如何加密解密RAR文件
    目录实践过程效果代码实践过程 效果 代码 public partial class Form1 : Form { public Form1() { ...
    99+
    2022-12-31
    C#加密解密RAR文件 C#加密RAR C#解密RAR
  • python 破解加密zip文件的密码
    目录今天的文章来自 盏茶作酒 同学。他在老电脑中发现了一个加密的 zip 文件,于是用 Python 破解了文件密码。在破解的过程中出现了内存爆炸的问题,通过阅读 Python 源代...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作