封装的方法类
This commit is contained in:
@@ -0,0 +1,361 @@
|
||||
package cryptx
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
LETTERDIGITS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
LD_COUNT = 62
|
||||
)
|
||||
|
||||
const (
|
||||
WXBizMsgCrypt_OK = 0
|
||||
WXBizMsgCrypt_ValidateSignature_Error = -40001
|
||||
WXBizMsgCrypt_ParseXml_Error = -40002
|
||||
WXBizMsgCrypt_ComputeSignature_Error = -40003
|
||||
WXBizMsgCrypt_IllegalAesKey = -40004
|
||||
WXBizMsgCrypt_ValidateAppid_Error = -40005
|
||||
WXBizMsgCrypt_EncryptAES_Error = -40006
|
||||
WXBizMsgCrypt_DecryptAES_Error = -40007
|
||||
WXBizMsgCrypt_IllegalBuffer = -40008
|
||||
WXBizMsgCrypt_EncodeBase64_Error = -40009
|
||||
WXBizMsgCrypt_DecodeBase64_Error = -40010
|
||||
WXBizMsgCrypt_GenReturnXml_Error = -40011
|
||||
)
|
||||
|
||||
var (
|
||||
letterDigitArr = []byte(LETTERDIGITS)
|
||||
)
|
||||
|
||||
type (
|
||||
XMLParse struct {
|
||||
XMLtmpl string
|
||||
}
|
||||
|
||||
WXBizMsgCrypt interface {
|
||||
EncryptMsg(sReplyMsg string, sNonce string, timestamp int64) (int, string)
|
||||
DecryptMsg(sPostData, sMsgSignature string, sTimeStamp int64, sNonce string) (int, string)
|
||||
}
|
||||
|
||||
wxBizMsgCrypt struct {
|
||||
key string
|
||||
token string
|
||||
appid string
|
||||
}
|
||||
)
|
||||
|
||||
// sToken: 公众平台上,开发者设置的Token
|
||||
// sEncodingAESKey: 公众平台上,开发者设置的EncodingAESKey
|
||||
// sAppId: 企业号的AppId
|
||||
func NewWXBizMsgCrypt(sToken, sEncodingAESKey, sAppId string) (WXBizMsgCrypt, error) {
|
||||
decodeBytes, err := base64.StdEncoding.DecodeString(sEncodingAESKey + "=")
|
||||
if err != nil {
|
||||
return nil, errors.New("EncodingAESKey err")
|
||||
}
|
||||
//assert len(key) == 32
|
||||
if len(decodeBytes) != 32 {
|
||||
return nil, errors.New("EncodingAESKey length err")
|
||||
}
|
||||
c := &wxBizMsgCrypt{
|
||||
key: string(decodeBytes),
|
||||
token: sToken,
|
||||
appid: sAppId,
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// 将公众号回复用户的消息加密打包
|
||||
// sReplyMsg: 企业号待回复用户的消息,xml格式的字符串
|
||||
// sTimeStamp: 时间戳,可以自己生成,也可以用URL参数的timestamp,如为None则自动用当前时间
|
||||
// sNonce: 随机串,可以自己生成,也可以用URL参数的nonce
|
||||
// sEncryptMsg: 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串,
|
||||
// return:成功0,sEncryptMsg,失败返回对应的错误码None
|
||||
func (c *wxBizMsgCrypt) EncryptMsg(sReplyMsg string, sNonce string, timestamp int64) (int, string) {
|
||||
pc := NewPrpcrypt(c.key)
|
||||
ret, encryptBytes := pc.encrypt([]byte(sReplyMsg), c.appid)
|
||||
if ret != WXBizMsgCrypt_OK {
|
||||
return ret, ""
|
||||
}
|
||||
if timestamp <= 0 {
|
||||
timestamp = time.Now().Unix()
|
||||
}
|
||||
encrypt_text := string(encryptBytes)
|
||||
timestampStr := fmt.Sprintf("%d", timestamp)
|
||||
// 生成安全签名
|
||||
ret, signature := getSHA1(c.token, timestampStr, sNonce, encrypt_text)
|
||||
if ret != WXBizMsgCrypt_OK {
|
||||
return ret, ""
|
||||
}
|
||||
xmlParse := NewXMLParse()
|
||||
resp_xml := xmlParse.generate(encrypt_text, signature, timestampStr, sNonce)
|
||||
return ret, resp_xml
|
||||
}
|
||||
|
||||
// 检验消息的真实性,并且获取解密后的明文
|
||||
// sMsgSignature: 签名串,对应URL参数的msg_signature
|
||||
// sTimeStamp: 时间戳,对应URL参数的timestamp
|
||||
// sNonce: 随机串,对应URL参数的nonce
|
||||
// sPostData: 密文,对应POST请求的数据
|
||||
// xml_content: 解密后的原文,当return返回0时有效
|
||||
// return: 成功0,失败返回对应的错误码
|
||||
// 验证安全签名
|
||||
func (c *wxBizMsgCrypt) DecryptMsg(sPostData, sMsgSignature string, sTimeStamp int64, sNonce string) (int, string) {
|
||||
// 验证安全签名
|
||||
xmlParse := NewXMLParse()
|
||||
ret, encrypt, _ := xmlParse.extract(sPostData)
|
||||
if ret != WXBizMsgCrypt_OK {
|
||||
return ret, ""
|
||||
}
|
||||
timestampStr := fmt.Sprintf("%d", sTimeStamp)
|
||||
ret, signature := getSHA1(c.token, timestampStr, sNonce, encrypt)
|
||||
if ret != WXBizMsgCrypt_OK {
|
||||
return ret, ""
|
||||
}
|
||||
if signature != sMsgSignature {
|
||||
return WXBizMsgCrypt_ValidateSignature_Error, ""
|
||||
}
|
||||
pc := NewPrpcrypt(c.key)
|
||||
ret, xml_content := pc.decrypt([]byte(encrypt), c.appid)
|
||||
return ret, string(xml_content)
|
||||
}
|
||||
|
||||
// 提供提取消息格式中的密文及生成回复消息格式的接口
|
||||
func NewXMLParse() *XMLParse {
|
||||
xp := &XMLParse{
|
||||
// xml消息模板
|
||||
XMLtmpl: `<xml>
|
||||
<Encrypt><![CDATA[%(msg_encrypt)s]]></Encrypt>
|
||||
<MsgSignature><![CDATA[%(msg_signaturet)s]]></MsgSignature>
|
||||
<TimeStamp>%(timestamp)s</TimeStamp>
|
||||
<Nonce><![CDATA[%(nonce)s]]></Nonce>
|
||||
</xml>`,
|
||||
}
|
||||
return xp
|
||||
}
|
||||
|
||||
type XmlResources struct {
|
||||
XMLName xml.Name `xml:"xml"`
|
||||
Encrypt string `xml:"Encrypt"`
|
||||
ToUserName string `xml:"ToUserName"`
|
||||
}
|
||||
|
||||
// 提取出xml数据包中的加密消息
|
||||
// xmltext: 待提取的xml字符串
|
||||
// return: 提取出的加密消息字符串
|
||||
//
|
||||
func (xp *XMLParse) extract(xmltext string) (int, string, string) {
|
||||
var result XmlResources
|
||||
err := xml.Unmarshal([]byte(xmltext), &result)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return WXBizMsgCrypt_ParseXml_Error, "", ""
|
||||
}
|
||||
return WXBizMsgCrypt_OK, result.Encrypt, result.ToUserName
|
||||
}
|
||||
|
||||
// 生成xml消息
|
||||
// encrypt: 加密后的消息密文
|
||||
// signature: 安全签名
|
||||
// timestamp: 时间戳
|
||||
// nonce: 随机字符串
|
||||
// return: 生成的xml字符串
|
||||
//
|
||||
func (xp *XMLParse) generate(encrypt, signature, timestampStr, nonce string) string {
|
||||
resp_xml := strings.Replace(xp.XMLtmpl, "%(msg_encrypt)s", encrypt, 1)
|
||||
resp_xml = strings.Replace(resp_xml, "%(msg_signaturet)s", signature, 1)
|
||||
resp_xml = strings.Replace(resp_xml, "%(timestamp)s", timestampStr, 1)
|
||||
resp_xml = strings.Replace(resp_xml, "%(nonce)s", nonce, 1)
|
||||
return resp_xml
|
||||
}
|
||||
|
||||
// 计算公众平台的消息签名接口
|
||||
// 用SHA1算法生成安全签名
|
||||
// token: 票据
|
||||
// timestamp: 时间戳
|
||||
// encrypt: 密文
|
||||
// nonce: 随机字符串
|
||||
// return: 安全签名
|
||||
func getSHA1(token string, timestampStr, nonce, encrypt string) (int, string) {
|
||||
sortlist := []string{token, timestampStr, nonce, encrypt}
|
||||
sort.Strings(sortlist)
|
||||
hashBytes := sha1.Sum([]byte(strings.Join(sortlist, "")))
|
||||
hashString := fmt.Sprintf("%x", hashBytes)
|
||||
return WXBizMsgCrypt_OK, hashString
|
||||
}
|
||||
|
||||
type Prpcrypt struct {
|
||||
key string
|
||||
mode string
|
||||
}
|
||||
|
||||
// 提供接收和推送给公众平台消息的加解密接口
|
||||
func NewPrpcrypt(key string) *Prpcrypt {
|
||||
// 设置加解密模式为AES的CBC模式
|
||||
pc := &Prpcrypt{
|
||||
key: key,
|
||||
mode: "AES.CBC",
|
||||
}
|
||||
return pc
|
||||
}
|
||||
|
||||
// s对明文进行加密
|
||||
// textBytes: 需要加密的明文
|
||||
// return: 加密得到的字符串
|
||||
//
|
||||
func (pc *Prpcrypt) encrypt(textBytes []byte, appid string) (int, []byte) {
|
||||
//# 16位随机字符串添加到明文开头
|
||||
rand_bytes := pc.get_random_bytes()
|
||||
len1 := len(rand_bytes)
|
||||
len3 := len(textBytes)
|
||||
len_bytes := htonl(len3)
|
||||
len2 := len(len_bytes)
|
||||
appid_bytes := []byte(appid)
|
||||
len4 := len(appid_bytes)
|
||||
toBytes := make([]byte, len1+len2+len3+len4)
|
||||
copy(toBytes[0:len1], rand_bytes)
|
||||
copy(toBytes[len1:(len1+len2)], len_bytes)
|
||||
copy(toBytes[(len1+len2):(len1+len2+len3)], textBytes)
|
||||
copy(toBytes[(len1+len2+len3):(len1+len2+len3+len4)], appid_bytes)
|
||||
// 使用自定义的填充方式对明文进行补位填充
|
||||
pkcs7 := NewPKCS7Encoder()
|
||||
plantBytes := pkcs7.encode(toBytes)
|
||||
// 加密
|
||||
keyBytes := []byte(pc.key)
|
||||
block, err := aes.NewCipher(keyBytes) //选择加密算法
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return WXBizMsgCrypt_EncryptAES_Error, []byte{}
|
||||
}
|
||||
blockModel := cipher.NewCBCEncrypter(block, keyBytes[0:16])
|
||||
cipherBytes := make([]byte, len(plantBytes))
|
||||
blockModel.CryptBlocks(cipherBytes, plantBytes)
|
||||
// 使用BASE64对加密后的字符串进行编码
|
||||
dstBytes := make([]byte, base64.StdEncoding.EncodedLen(len(cipherBytes)))
|
||||
base64.StdEncoding.Encode(dstBytes, cipherBytes)
|
||||
return WXBizMsgCrypt_OK, dstBytes
|
||||
}
|
||||
|
||||
// 对解密后的明文进行补位删除
|
||||
// cipherBytes: 密文
|
||||
// return: 删除填充补位后的明文
|
||||
//
|
||||
func (pc *Prpcrypt) decrypt(cipherBytes []byte, appid string) (int, []byte) {
|
||||
_dstBytes := make([]byte, base64.StdEncoding.DecodedLen(len(cipherBytes)))
|
||||
n, err := base64.StdEncoding.Decode(_dstBytes, cipherBytes)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return WXBizMsgCrypt_DecodeBase64_Error, []byte{}
|
||||
}
|
||||
dstBytes := _dstBytes[0:n]
|
||||
keyBytes := []byte(pc.key)
|
||||
block, err := aes.NewCipher(keyBytes) //选择加密算法
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return WXBizMsgCrypt_IllegalBuffer, []byte{}
|
||||
}
|
||||
blockModel := cipher.NewCBCDecrypter(block, keyBytes[0:16])
|
||||
plantBytes := make([]byte, len(dstBytes))
|
||||
blockModel.CryptBlocks(plantBytes, dstBytes)
|
||||
//
|
||||
length := len(plantBytes)
|
||||
pad := int(uint8(plantBytes[length-1]))
|
||||
// 去除16位随机字符串
|
||||
content := plantBytes[16:(length - pad)]
|
||||
xml_len := ntohl(content[0:4])
|
||||
xml_content := content[4:(xml_len + 4)]
|
||||
from_appid := content[(xml_len + 4):len(content)]
|
||||
if string(from_appid) != appid {
|
||||
return WXBizMsgCrypt_ValidateAppid_Error, []byte{}
|
||||
}
|
||||
return WXBizMsgCrypt_OK, xml_content
|
||||
|
||||
}
|
||||
|
||||
// 随机生成16位字符串
|
||||
// return: 16位字符串
|
||||
//
|
||||
func (pc *Prpcrypt) get_random_bytes() []byte {
|
||||
rander := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
length := 16
|
||||
result := make([]byte, length)
|
||||
for i, _ := range result {
|
||||
result[i] = letterDigitArr[rander.Intn(LD_COUNT)]
|
||||
//result[i] = letterDigitArr[52+((i+1)%10)]
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 提供基于PKCS7算法的加解密接口
|
||||
type PKCS7Encoder struct {
|
||||
block_size int
|
||||
}
|
||||
|
||||
func NewPKCS7Encoder() *PKCS7Encoder {
|
||||
p := &PKCS7Encoder{
|
||||
block_size: 32,
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// 对需要加密的明文进行填充补位
|
||||
// text: 需要进行填充补位操作的明文
|
||||
// return: 补齐明文字符串
|
||||
func (p *PKCS7Encoder) encode(textBytes []byte) []byte {
|
||||
length := len(textBytes)
|
||||
if length == 0 {
|
||||
return []byte{}
|
||||
}
|
||||
// 计算需要填充的位数
|
||||
amount_to_pad := p.block_size - (length % p.block_size)
|
||||
if amount_to_pad == 0 {
|
||||
amount_to_pad = p.block_size
|
||||
}
|
||||
// 获得补位所用的字符
|
||||
padArr := bytes.Repeat([]byte{byte(amount_to_pad)}, amount_to_pad)
|
||||
encTextBytes := make([]byte, length+amount_to_pad)
|
||||
copy(encTextBytes, textBytes)
|
||||
copy(encTextBytes[length:(length+amount_to_pad)], padArr)
|
||||
return encTextBytes
|
||||
}
|
||||
|
||||
// 删除解密后明文的补位字符
|
||||
// decrypted: 解密后的明文
|
||||
// return: 删除补位字符后的明文
|
||||
func (p *PKCS7Encoder) decode(decrypted []byte) []byte {
|
||||
length := len(decrypted)
|
||||
if length == 0 {
|
||||
return []byte{}
|
||||
}
|
||||
pad := int(uint8(decrypted[length-1]))
|
||||
if pad < 1 || pad > 32 {
|
||||
pad = 0
|
||||
}
|
||||
if pad >= length {
|
||||
return []byte{}
|
||||
}
|
||||
return decrypted[0:(length - pad)]
|
||||
}
|
||||
|
||||
func htonl(n int) []byte {
|
||||
data := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(data, uint32(n))
|
||||
return data
|
||||
}
|
||||
|
||||
func ntohl(data []byte) int {
|
||||
n := binary.BigEndian.Uint32(data[0:4])
|
||||
return int(n)
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package cryptx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestWXBizMsgCrypt(t *testing.T) {
|
||||
// 1.第三方回复加密消息给公众平台;
|
||||
// 2.第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。
|
||||
encodingAESKey := "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG"
|
||||
token := "spamtest"
|
||||
appid := "wx2c2769f8efd9abc2"
|
||||
timestamp := int64(1409735669)
|
||||
|
||||
to_xml := ` <xml><ToUserName><![CDATA[oia2TjjewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType> <![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo中文]]></Title><Descript ion><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>`
|
||||
nonce := "1320562132"
|
||||
// 测试加密接口
|
||||
cryp_test, err := NewWXBizMsgCrypt(token, encodingAESKey, appid)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ret, encrypt_xml := cryp_test.EncryptMsg(to_xml, nonce, timestamp)
|
||||
fmt.Println(ret)
|
||||
fmt.Println(encrypt_xml)
|
||||
|
||||
msg_sign := "ea7a2ac5580e3c67d663b42c63b976b7e2bf26b9"
|
||||
from_xml := `<xml><Encrypt><![CDATA[QCTqNwyPmqRu4xuyqVsja3pIr0TeNW/5tIi3Ul+15UnsdXcZoLmTZJtCxJn7e5lKBp7A5lykhD8Hsejz9M+OBTXLrkuqRD0Ky0fkfk4ZCIZhHc+pWuNZjalZGDQ3tzz2rCfn2pzEHGE3jnSWP4EdLdailWTo/Hz7gxBnLf2xI3xsS9kxyErmv14LhdccB7hVqa224efcb5lT85XKfrku7b4W5L7MA6g8/TYBFrkHCZz9l9sjMgEzNkErAHdayzM6eKCOUm51PQv0Sp3jPjq7NEUi9DZa8nnrz/w3P5clO+Hmf6yqwJZAE26+nGYtltcZmOu8UCZrqZDkAD+MwPeYSGo4C1j6R71zsBwI3sk/Bea52AAGqjvGVPGK3oTvku775T93MwTzjJMZTxX3xF2QrPbbU5pFIBZWF8KW0Giuqui500qRz9Ix5oVK3TK4ZCCZpHJelUvy5gcP4ldbDStZhQaM21pdlitL6Kt/GucIpIWHkxiObKu1pBfU94cR0ZCgoja8E6xtx+cGMIgCN33/QHkwM+xeb6rCF0HhDZwd9TwdetxpRbqRDkfzc+LaeoF8HHbFhK+3tKP9qZBAdZm1v4YUFK2db1juaoyXHAXFDn3I8PZ5zSP8vddBDSfoLgv+]]></Encrypt><MsgSignature><![CDATA[ea7a2ac5580e3c67d663b42c63b976b7e2bf26b9]]></MsgSignature><TimeStamp>1409735669</TimeStamp><Nonce><![CDATA[1320562132]]></Nonce></xml>`
|
||||
|
||||
// 测试解密接口
|
||||
//msg_sign := "5d197aaffba7e9b25a30732f161a50dee96bd5fa"
|
||||
//from_xml := `<xml><ToUserName><![CDATA[gh_10f6c3c3ac5a]]></ToUserName><FromUserName><![CDATA[oyORnuP8q7ou2gfYjqLzSIWZf0rs]]></FromUserName><CreateTime>1409735668</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[abcdteT]]></Content><MsgId>6054768590064713728</MsgId><Encrypt><![CDATA[hyzAe4OzmOMbd6TvGdIOO6uBmdJoD0Fk53REIHvxYtJlE2B655HuD0m8KUePWB3+LrPXo87wzQ1QLvbeUgmBM4x6F8PGHQHFVAFmOD2LdJF9FrXpbUAh0B5GIItb52sn896wVsMSHGuPE328HnRGBcrS7C41IzDWyWNlZkyyXwon8T332jisa+h6tEDYsVticbSnyU8dKOIbgU6ux5VTjg3yt+WGzjlpKn6NPhRjpA912xMezR4kw6KWwMrCVKSVCZciVGCgavjIQ6X8tCOp3yZbGpy0VxpAe+77TszTfRd5RJSVO/HTnifJpXgCSUdUue1v6h0EIBYYI1BD1DlD+C0CR8e6OewpusjZ4uBl9FyJvnhvQl+q5rv1ixrcpCumEPo5MJSgM9ehVsNPfUM669WuMyVWQLCzpu9GhglF2PE=]]></Encrypt></xml>`
|
||||
ret, decryp_xml := cryp_test.DecryptMsg(from_xml, msg_sign, timestamp, nonce)
|
||||
fmt.Println(ret)
|
||||
fmt.Println(decryp_xml)
|
||||
}
|
||||
|
||||
func TestWXBizMsgCrypt2(t *testing.T) {
|
||||
// 1.第三方回复加密消息给公众平台;
|
||||
// 2.第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。
|
||||
encodingAESKey := "E7MKT2IwQzLCxtzc1sjeqjPrftqGFLxomFSv2py0UNx"
|
||||
token := "weixin"
|
||||
appid := "wx4e7d601bea5a8093"
|
||||
timestamp := int64(1680706178)
|
||||
|
||||
// to_xml := ` <xml><ToUserName><![CDATA[oia2TjjewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType> <![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo中文]]></Title><Descript ion><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>`
|
||||
nonce := "1536850936"
|
||||
// // 测试加密接口
|
||||
cryp_test, err := NewWXBizMsgCrypt(token, encodingAESKey, appid)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// ret, encrypt_xml := cryp_test.EncryptMsg(to_xml, nonce, timestamp)
|
||||
// fmt.Println(ret)
|
||||
// fmt.Println(encrypt_xml)
|
||||
|
||||
msg_sign := "34d5a40b6e17013f0e0aa2e48de98355c15ba6c6"
|
||||
from_xml := `<xml>
|
||||
<ToUserName><![CDATA[gh_cdfaacccfe8d]]></ToUserName>
|
||||
<Encrypt><![CDATA[JGi3SHl4GFSzQ2axn/k0PUTm7O3tF1+PXdZ+rrHRrwxaYJFF+PmT1K+jZ9NrlsXjcdSgDeN34DV4VkYKRRTPZ1W0SD0w6H7AlMeC8tlSSpEEPMmNisu3+13OHyExzWgXWt+Fu54HGhrOJkIf8dWHVwOXv/ulwmU857iL8yrIYPH2i4mXjSJxLivdrmp+5o3i+DxzKC5FdeDxZtBgLNxnFsW/MxOjC7+SHo/0SQtiMbhwkR9ByNzirxNSUcUuEJnYTX9gHRoaaiEkaf/T+s3ZuLa2NlHkGlWCMDJQK87SrsKUfsVcfx6Ihde0sTxeAkiIBdWrzjcvMT8SEqmx8bWI9BtSc9ya+nvo0MT/BP7fvnCDRy23l2KtimHImmT+q5MzsESFK+bTU5Afcmn9m55QmdmW7ArPz+AFciwaIJrjtXyV3KNCZW64m+UfUUDAOVxtT7NtPQXaZNy8O1HV1zJnW7YOltTmNvZV+hRAbOKBk4C1Lqv1ekf8I8e2y4/STxPL]]></Encrypt>
|
||||
</xml>`
|
||||
|
||||
// 测试解密接口
|
||||
//msg_sign := "5d197aaffba7e9b25a30732f161a50dee96bd5fa"
|
||||
//from_xml := `<xml><ToUserName><![CDATA[gh_10f6c3c3ac5a]]></ToUserName><FromUserName><![CDATA[oyORnuP8q7ou2gfYjqLzSIWZf0rs]]></FromUserName><CreateTime>1409735668</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[abcdteT]]></Content><MsgId>6054768590064713728</MsgId><Encrypt><![CDATA[hyzAe4OzmOMbd6TvGdIOO6uBmdJoD0Fk53REIHvxYtJlE2B655HuD0m8KUePWB3+LrPXo87wzQ1QLvbeUgmBM4x6F8PGHQHFVAFmOD2LdJF9FrXpbUAh0B5GIItb52sn896wVsMSHGuPE328HnRGBcrS7C41IzDWyWNlZkyyXwon8T332jisa+h6tEDYsVticbSnyU8dKOIbgU6ux5VTjg3yt+WGzjlpKn6NPhRjpA912xMezR4kw6KWwMrCVKSVCZciVGCgavjIQ6X8tCOp3yZbGpy0VxpAe+77TszTfRd5RJSVO/HTnifJpXgCSUdUue1v6h0EIBYYI1BD1DlD+C0CR8e6OewpusjZ4uBl9FyJvnhvQl+q5rv1ixrcpCumEPo5MJSgM9ehVsNPfUM669WuMyVWQLCzpu9GhglF2PE=]]></Encrypt></xml>`
|
||||
ret, decryp_xml := cryp_test.DecryptMsg(from_xml, msg_sign, timestamp, nonce)
|
||||
fmt.Println(ret)
|
||||
fmt.Println(decryp_xml)
|
||||
}
|
||||
Reference in New Issue
Block a user