|
- package main
-
- import (
- "crypto/aes"
- "crypto/cipher"
- "encoding/base64"
- "fmt"
- )
-
- const txt = "P2DoRtilYwJ1aM+VW1sGs6p11Rhcd/TrFYtvsw53SUVw2Knh27hF5IZUBxRXbz+k87zy983ec5aOwgS+WxYoejmGubaqiYy2yfCBNyGRlWfe+iWc2TnvPIEAJebSWuNOJ7FoITeMndr4tW391XxDdMom8I/VsqKnsZZAangUsxmA1ZEnP/d4Lx8/xt3qJKrJMa4Q8s9VsOOvzLIGhL1IN5bHaXN+CwgBTAUCrHD8AneiX5MLSv/74qozg+jKBSUebZrjRYuTymQ3TBh3pQXyRBQTZNrCAe1tlcNli9e5MSUMsHFIzGw/kiu93/5VkxCYRLgRDQKl9oam4+Rpxywir7EiT7I4X343l9ogcMLWX16evkLlQHoqBhLl6ZcfW7Nmq8/Ghy8jbuwqkR/0jLJ/avtjzgJOwaxdBUz4nYZ452rLJekxIvsmV6PZgCXRrKHzmpZX+i6hIRIWiIaDeMOEsw=="
-
- //Decode Decode encrypt string to xml context
- func Decode(s string) string {
-
- r, _ := base64.StdEncoding.DecodeString(txt)
-
- key, _ := base64.StdEncoding.DecodeString(APIConfig.EncodingAESKey + "=")
- var k [32]byte
- copy(k[:], key)
- random, raw, err := AESDecryptMsg([]byte(r), APIConfig.Appid, k)
-
- fmt.Println(len(txt))
- fmt.Println(random)
- fmt.Println(string(raw))
-
- bc, err := aes.NewCipher([]byte(key))
- if err == nil {
- fmt.Printf("The block size is %d\n", bc.BlockSize())
- var decoded = make([]byte, 4096)
- bc.Decrypt(decoded, r)
- //AES Decode
- }
- fmt.Printf("%s", string(r))
- return string(r)
- }
-
- // 把整数 n 格式化成 4 字节的网络字节序
- func encodeNetworkBytesOrder(orderBytes []byte, n int) {
- if len(orderBytes) != 4 {
- panic("the length of orderBytes must be equal to 4")
- }
- orderBytes[0] = byte(n >> 24)
- orderBytes[1] = byte(n >> 16)
- orderBytes[2] = byte(n >> 8)
- orderBytes[3] = byte(n)
- }
-
- // 从 4 字节的网络字节序里解析出整数
- func decodeNetworkBytesOrder(orderBytes []byte) (n int) {
- if len(orderBytes) != 4 {
- panic("the length of orderBytes must be equal to 4")
- }
- n = int(orderBytes[0])<<24 |
- int(orderBytes[1])<<16 |
- int(orderBytes[2])<<8 |
- int(orderBytes[3])
- return
- }
-
- //AESEncryptMsg encryptedMsg = AES_Encrypt[random(16B) + msg_len(4B) + rawXMLMsg + AppId]
- func AESEncryptMsg(random, rawXMLMsg []byte, AppId string, AESKey [32]byte) (encryptedMsg []byte) {
- const BLOCK_SIZE = 32 // PKCS#7
-
- buf := make([]byte, 20+len(rawXMLMsg)+len(AppId)+BLOCK_SIZE)
- plain := buf[:20]
- pad := buf[len(buf)-BLOCK_SIZE:]
-
- // 拼接
- copy(plain, random)
- encodeNetworkBytesOrder(plain[16:20], len(rawXMLMsg))
- plain = append(plain, rawXMLMsg...)
- plain = append(plain, AppId...)
-
- // PKCS#7 补位
- amountToPad := BLOCK_SIZE - len(plain)%BLOCK_SIZE
- for i := 0; i < amountToPad; i++ {
- pad[i] = byte(amountToPad)
- }
- plain = buf[:len(plain)+amountToPad]
-
- // 加密
- block, err := aes.NewCipher(AESKey[:])
- if err != nil {
- panic(err)
- }
- mode := cipher.NewCBCEncrypter(block, AESKey[:16])
- mode.CryptBlocks(plain, plain)
-
- encryptedMsg = plain
- return
- }
-
- // encryptedMsg = AES_Encrypt[random(16B) + msg_len(4B) + rawXMLMsg + AppId]
- func AESDecryptMsg(encryptedMsg []byte, AppId string, AESKey [32]byte) (random, rawXMLMsg []byte, err error) {
- const BLOCK_SIZE = 32 // PKCS#7
-
- if len(encryptedMsg) < BLOCK_SIZE {
- err = fmt.Errorf("the length of encryptedMsg too short: %d", len(encryptedMsg))
- return
- }
- if len(encryptedMsg)%BLOCK_SIZE != 0 {
- err = fmt.Errorf("encryptedMsg is not a multiple of the block size, the length is %d", len(encryptedMsg))
- return
- }
-
- plain := make([]byte, len(encryptedMsg)) // len(plain) >= BLOCK_SIZE
-
- // 解密
- block, err := aes.NewCipher(AESKey[:])
- if err != nil {
- panic(err)
- }
- mode := cipher.NewCBCDecrypter(block, AESKey[:16])
- mode.CryptBlocks(plain, encryptedMsg)
-
- // PKCS#7 去除补位
- amountToPad := int(plain[len(plain)-1])
- if amountToPad < 1 || amountToPad > BLOCK_SIZE {
- err = fmt.Errorf("the amount to pad is invalid: %d", amountToPad)
- return
- }
- plain = plain[:len(plain)-amountToPad]
-
- // 反拼装
- // len(plain) == 16+4+len(rawXMLMsg)+len(AppId)
- // len(AppId) > 0
- if len(plain) <= 20 {
- err = fmt.Errorf("plain msg too short, the length is %d", len(plain))
- return
- }
- msgLen := decodeNetworkBytesOrder(plain[16:20])
- if msgLen < 0 {
- err = fmt.Errorf("invalid msg length: %d", msgLen)
- return
- }
- msgEnd := 20 + msgLen
- if len(plain) <= msgEnd {
- err = fmt.Errorf("msg length too large: %d", msgLen)
- return
- }
-
- AppIdHave := string(plain[msgEnd:])
- if AppIdHave != AppId { // crypto/subtle.ConstantTimeCompare ???
- err = fmt.Errorf("AppId mismatch, have: %s, want: %s", AppIdHave, AppId)
- return
- }
-
- random = plain[:16:16]
- rawXMLMsg = plain[20:msgEnd]
- return
- }
|