Skip to content

Commit

Permalink
Add SHA1, CryptMsg methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
CharLemAznable committed Nov 16, 2018
1 parent 45f79d3 commit d6d45e6
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Wechat AES

提供接收和推送给微信公众平台消息的加解密接口

参见微信开放平台->第三方平台->[消息加解密接入指引](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419318479&token=&lang=zh_CN)
47 changes: 47 additions & 0 deletions crypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/xml"
"fmt"
mathRand "math/rand"
"time"
)
Expand Down Expand Up @@ -40,6 +42,51 @@ func WechatCryptorRandomStr() string {
return string(result)
}

const WechatCryptorEncryptMsgFormat = `
<xml>
<Encrypt><![CDATA[%s]]></Encrypt>
<MsgSignature><![CDATA[%s]]></MsgSignature>
<TimeStamp>%s</TimeStamp>
<Nonce><![CDATA[%s]]></Nonce>
</xml>
`

func (cryptor *WechatCryptor) EncryptMsg(msg, timeStamp, nonce string) (string, error) {
encrypt, err := cryptor.Encrypt(WechatCryptorRandomStr(), msg)
if nil != err {
return "", err
}

if 0 == len(timeStamp) {
timeStamp = string(time.Now().Unix())
}

sign := SHA1(cryptor.token, timeStamp, nonce, encrypt)
return fmt.Sprintf(WechatCryptorEncryptMsgFormat, encrypt, sign, timeStamp, nonce), nil
}

type WechatCryptorPostBody struct {
XMLName xml.Name `xml:"xml"`
ToUserName string `xml:"ToUserName"`
AppId string `xml:"AppId"`
Encrypt string `xml:"Encrypt"`
}

func (cryptor *WechatCryptor) DecryptMsg(msgSign, timeStamp, nonce, postData string) (string, error) {
postBody := WechatCryptorPostBody{}
err := xml.Unmarshal([]byte(postData), &postBody)
if nil != err || 0 == len(postBody.Encrypt) {
return "", &WechatCryptorError{Code: ParseXmlError}
}

sign := SHA1(cryptor.token, timeStamp, nonce, postBody.Encrypt)
if msgSign != sign {
return "", &WechatCryptorError{Code: ValidateSignatureError}
}

return cryptor.Decrypt(postBody.Encrypt)
}

// 对明文进行加密
func (cryptor *WechatCryptor) Encrypt(randomStr, text string) (string, error) {
randomBytes := []byte(randomStr)
Expand Down
32 changes: 26 additions & 6 deletions crypt_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package wechataes

import (
"encoding/xml"
"fmt"
"testing"
)
Expand All @@ -11,30 +12,49 @@ var encodingAesKey = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG"
var randomStr = "aaaabbbbccccdddd"
var replyMsg = "我是中文abcd123"
var afterAesEncrypt = "jn1L23DB+6ELqJ+6bruv21Y6MD7KeIfP82D6gU39rmkgczbWwt5+3bnyg5K55bgVtVzd832WzZGMhkP72vVOfg=="
var replyMsg2 = "<xml><ToUserName><![CDATA[oia2Tj我是中文jewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo]]></Title><Description><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>";
var replyMsg2 = "<xml><ToUserName><![CDATA[oia2Tj我是中文jewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo]]></Title><Description><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>"
var afterAesEncrypt2 = "jn1L23DB+6ELqJ+6bruv23M2GmYfkv0xBh2h+XTBOKVKcgDFHle6gqcZ1cZrk3e1qjPQ1F4RsLWzQRG9udbKWesxlkupqcEcW7ZQweImX9+wLMa0GaUzpkycA8+IamDBxn5loLgZpnS7fVAbExOkK5DYHBmv5tptA9tklE/fTIILHR8HLXa5nQvFb3tYPKAlHF3rtTeayNf0QuM+UW/wM9enGIDIJHF7CLHiDNAYxr+r+OrJCmPQyTy8cVWlu9iSvOHPT/77bZqJucQHQ04sq7KZI27OcqpQNSto2OdHCoTccjggX5Z9Mma0nMJBU+jLKJ38YB1fBIz+vBzsYjrTmFQ44YfeEuZ+xRTQwr92vhA9OxchWVINGC50qE/6lmkwWTwGX9wtQpsJKhP+oS7rvTY8+VdzETdfakjkwQ5/Xka042OlUb1/slTwo4RscuQ+RdxSGvDahxAJ6+EAjLt9d8igHngxIbf6YyqqROxuxqIeIch3CssH/LqRs+iAcILvApYZckqmA7FNERspKA5f8GoJ9sv8xmGvZ9Yrf57cExWtnX8aCMMaBropU/1k+hKP5LVdzbWCG0hGwx/dQudYR/eXp3P0XxjlFiy+9DMlaFExWUZQDajPkdPrEeOwofJb"
var timestamp = "1409304348"
var nonce = "xxxxxx"

func TestNewWechatCryptor(t *testing.T) {
func TestWechatCrypt(t *testing.T) {
cryptor, _ := NewWechatCryptor(appId, token, encodingAesKey)
encrypt, _ := cryptor.Encrypt(randomStr, replyMsg)
fmt.Println(encrypt)
if afterAesEncrypt != encrypt {
t.Error("no异常")
}
decrypt, _ := cryptor.Decrypt(afterAesEncrypt)
fmt.Println(decrypt)
if replyMsg != decrypt {
t.Error("no异常")
}

encrypt2, _ := cryptor.Encrypt(randomStr, replyMsg2)
fmt.Println(encrypt2)
if afterAesEncrypt2 != encrypt2 {
t.Error("no异常")
}
decrypt2, _ := cryptor.Decrypt(afterAesEncrypt2)
fmt.Println(decrypt2)
if replyMsg2 != decrypt2 {
t.Error("no异常")
}
}

type TestEncryptMsg struct {
XMLName xml.Name `xml:"xml"`
Encrypt string `xml:"Encrypt"`
MsgSignature string `xml:"MsgSignature"`
}

func TestWechatCryptMsg(t *testing.T) {
cryptor, _ := NewWechatCryptor(appId, token, encodingAesKey)
afterEncrpt, _ := cryptor.EncryptMsg(replyMsg, timestamp, nonce)

encryptMsg := TestEncryptMsg{}
xml.Unmarshal([]byte(afterEncrpt), &encryptMsg)
format := "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>"
fromXML := fmt.Sprintf(format, encryptMsg.Encrypt)

afterDecrpt, _ := cryptor.DecryptMsg(encryptMsg.MsgSignature, timestamp, nonce, fromXML)
if replyMsg != afterDecrpt {
t.Error("no异常")
}
}
21 changes: 21 additions & 0 deletions sign.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package wechataes

import (
"crypto/sha1"
"encoding/hex"
"sort"
"strings"
)

func SHA1(token, timestamp, nonce, encrypt string) string {
array := []string{token, timestamp, nonce, encrypt}
sort.Strings(array)
str := strings.Join(array, "")

hash := sha1.New()
hash.Write([]byte(str))
sum := hash.Sum(nil)
sumHex := make([]byte, hex.EncodedLen(len(sum)))
hex.Encode(sumHex, sum)
return string(sumHex)
}
14 changes: 14 additions & 0 deletions sign_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package wechataes

import (
"testing"
)

var expectSHA1 = "82c962d39941aa48552f90ef55aa323dc620cc10"

func TestSHA1(t *testing.T) {
sha1 := SHA1(token, timestamp, nonce, afterAesEncrypt)
if expectSHA1 != sha1 {
t.Error("no异常")
}
}

0 comments on commit d6d45e6

Please sign in to comment.