Golang AES-128/GCM + BASE64 加密

需求背景:接入网络游戏防沉迷系统,其中请求体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请求
: )