参考 微信开放文档
当前端调用 getUserProfile 这个API 的时候,会返回一堆数据,userInfo 用户信息对象。。。
- 在解密 encryptedData 的时候,首先要通过 wx.login() 获取到 session_key
- 方法: 小程序调用 wx.login() 将 code 传给后端,后端通过这个 code 去获取到 session_keykey。在这儿要调用 jscode2session 微信的接口,传入参数参考文档
- 通过 AppID,session_key,encryptedData,iv。就可以解密 encryptedData里面的数据
- 因为我是使用 go 进行开发,go语言里面内置了 base64,所以不需要下载任何包。
package utils
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
)
// 微信小程序解密算法 AES-128-CBC
func DecryptWXOpenData(app_id, sessionKey, encryptData, iv string) (map[string]interface{}, error) {
decodeBytes, err := base64.StdEncoding.DecodeString(encryptData)
if err != nil {
return nil, err
}
sessionKeyBytes, errKey := base64.StdEncoding.DecodeString(sessionKey)
if errKey != nil {
return nil, errKey
}
ivBytes, errIv := base64.StdEncoding.DecodeString(iv)
if errIv != nil {
return nil, errIv
}
dataBytes, errData := aesDecrypt(decodeBytes, sessionKeyBytes, ivBytes)
fmt.Printf("dataBytes: %v\n", dataBytes)
if errData != nil {
return nil, errData
}
var result map[string]interface{}
errResult := json.Unmarshal(dataBytes, &result)
watermark := result["watermark"].(map[string]interface{})
if watermark["appid"] != app_id {
return nil, errors.New("Invalid appid data!")
}
return result, errResult
}
// AES 解密
func aesDecrypt(crypted, key, iv []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockMode := cipher.NewCBCDecrypter(block, iv)
// 原始数据
origData := make([]byte, len(crypted))
blockMode.CryptBlocks(origData, crypted)
// 去除填充 --- 数据尾端有'/x0e'占位符,去除它
length := len(origData)
unp := int(origData[length-1])
return origData[:(length - unp)], nil
}
主文件
func test(){
// appId 小程序的 AppID 一个固定的值
// session_key 通过调用 jscode2session 获得
// testEncryptedData 小程序传过来的
// testIv
appId := ""
session_key := ""
testEncryptedData := ""
testIv := ""
m, errData := utils.DecryptWXOpenData(appId, session_key , testEncryptedData, testIv)
if errData != nil {
return
}
fmt.Printf("解密后的数据: %v\n", m)
}