过春社了,度帘幕中间,去年尘冷。——史达祖《双双燕·咏燕》
需求背景:接入网络游戏防沉迷系统,其中请求体body需要进行加密,和签名
废话不多说,就直接上源码
加密
func GCMEncrypt(secretKey, originalText string) (string, error) {
// 密钥需要解码
key, _ := hex.DecodeString(secretKey)
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
aesGcm, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
// 向量
nonce := make([]byte, aesGcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return "", err
}
cipherText := aesGcm.Seal(nonce, nonce, []byte(originalText), nil)
// encode as base64 string
encoded := base64.StdEncoding.EncodeToString(cipherText)
return encoded, nil
}
签名
func (s *encryptService) Sign(headers, body map[string]string) string {
var data string
var keys []string
// key排序
for k := range headers {
keys = append(keys, k)
}
sort.Strings(keys)
// 拼接
for _, k := range keys {
data = data + k + headers[k]
}
data = s.appSecret + data + gconv.String(body)
// 对字符串进行sha256哈希
h := sha256.New()
h.Write([]byte(data))
sum := h.Sum(nil)
return hex.EncodeToString(sum)
}
使用
// 参数初始化
headers := map[string]string{
"appId": "xxxxxxxx",
"bizId": "xxxxxxxx",
"timestamps": strconv.Itoa(int(time.Now().UnixNano() / 1e6)),
}
// 请求体加密
jsonByte, _ := json.Marshal(req)
cipher, _ := GCMEncrypt(string(jsonByte), 'xxxxxxxxx') // 第二个参数是密钥
body := map[string]string{
"data": cipher,
}
// 生成签名
headers["sign"] = Encrypt.Sign(headers, body)
headers["Content-Type"] = "application/json"
.....发http请求