diff --git a/Api_request.txt b/Api_request.txt index 44b74bd..f156e98 100644 --- a/Api_request.txt +++ b/Api_request.txt @@ -211,4 +211,11 @@ X-Forwarded-Server: wechat.hitxy.org.au 6411651983041024410 + + + +如果纯粹加密,没有明文 + + + \ No newline at end of file diff --git a/main.go b/main.go index 8788c1a..08a8af2 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,9 @@ func main() { log.Fatal("unable to read config, program quit") return } + + Decode("SS") + return //setup handler http.HandleFunc("/", webrootHandler) http.HandleFunc("/api", apiV1Main) diff --git a/messageEncrypt.go b/messageEncrypt.go new file mode 100644 index 0000000..c49741f --- /dev/null +++ b/messageEncrypt.go @@ -0,0 +1,151 @@ +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 +}