go GCM加密解密 gin中间件加密解密,gin文件流处理

本文介绍了如何在Gin框架下实现AES-GCM模式的加密解密,特别是在微服务环境中。针对不同类型的HTTP请求(GET、POST JSON、POST File、POST Form),文章提出了在网关服务中处理请求和响应流的加密解密方法。通过示例代码展示了加密解密程序、网关转发程序和Gin中间件的实现,并提供了一个DEMO程序以验证运行效果,包括GET请求、POST JSON、POST Form的处理以及文件上传下载功能。
摘要由CSDN通过智能技术生成

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

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

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

package aes

import (
	"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 middleware

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/valyala/fasthttp"
	"io/ioutil"
	"runtime/debug"
	"time"
)

var fastClient *fasthttp.Client

func init() {
	fastClient = &fasthttp.Client{}
	fastClient.MaxIdemponentCallAttempts = 1
	fastClient.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.Contex
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值