Go 语言 微信小程序加密数据解密算法实现

代码实现

本实现参考官方PHP例程实现,Go代码实现如下:

func DecryptData (app_id, session_key, iv, encrypted_data string) (map[string]interface{}, error) {
	if len := strings.Count(session_key, "") - 1; len != 24 {
		return nil, errors.New("Invalid value session_key!")
	}
	aesKey, err := base64.StdEncoding.DecodeString(session_key)
	if err != nil {
		return nil, err
	}

	if len := strings.Count(iv, "") - 1; len != 24 {
		return nil, errors.New("Invalid value iv!")
	}
	ivKey, err := base64.StdEncoding.DecodeString(iv)
	if err != nil {
		return nil, err
	}

	decodeData, err := base64.StdEncoding.DecodeString(encrypted_data)
	if err != nil {
		return nil, err
	}

	dataBytes, err := AesDecrypt(decodeData, aesKey, ivKey)
	if err != nil {
		return nil, err
	}

	var result map [string] interface{}
	err = json.Unmarshal(dataBytes, &result)

	watermark := result["watermark"].(map[string]interface{})
	if watermark["appid"] != app_id {
		return nil, errors.New("Invalid appid data!")
	}

	return result, err
}

参考

AES解密算法实现参考:golang版微信小程序登录和ase解码微信公开数据,稍作修改,代码如下:

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)
	
    // 去除填充
	length := len(origData)
	unp := int(origData[length-1])
	return origData[:(length - unp)], nil
}