Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

152 linhas
4.3KB

  1. package main
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "encoding/base64"
  6. "fmt"
  7. )
  8. const txt = "P2DoRtilYwJ1aM+VW1sGs6p11Rhcd/TrFYtvsw53SUVw2Knh27hF5IZUBxRXbz+k87zy983ec5aOwgS+WxYoejmGubaqiYy2yfCBNyGRlWfe+iWc2TnvPIEAJebSWuNOJ7FoITeMndr4tW391XxDdMom8I/VsqKnsZZAangUsxmA1ZEnP/d4Lx8/xt3qJKrJMa4Q8s9VsOOvzLIGhL1IN5bHaXN+CwgBTAUCrHD8AneiX5MLSv/74qozg+jKBSUebZrjRYuTymQ3TBh3pQXyRBQTZNrCAe1tlcNli9e5MSUMsHFIzGw/kiu93/5VkxCYRLgRDQKl9oam4+Rpxywir7EiT7I4X343l9ogcMLWX16evkLlQHoqBhLl6ZcfW7Nmq8/Ghy8jbuwqkR/0jLJ/avtjzgJOwaxdBUz4nYZ452rLJekxIvsmV6PZgCXRrKHzmpZX+i6hIRIWiIaDeMOEsw=="
  9. //Decode Decode encrypt string to xml context
  10. func Decode(s string) string {
  11. r, _ := base64.StdEncoding.DecodeString(txt)
  12. key, _ := base64.StdEncoding.DecodeString(APIConfig.EncodingAESKey + "=")
  13. var k [32]byte
  14. copy(k[:], key)
  15. random, raw, err := AESDecryptMsg([]byte(r), APIConfig.Appid, k)
  16. fmt.Println(len(txt))
  17. fmt.Println(random)
  18. fmt.Println(string(raw))
  19. bc, err := aes.NewCipher([]byte(key))
  20. if err == nil {
  21. fmt.Printf("The block size is %d\n", bc.BlockSize())
  22. var decoded = make([]byte, 4096)
  23. bc.Decrypt(decoded, r)
  24. //AES Decode
  25. }
  26. fmt.Printf("%s", string(r))
  27. return string(r)
  28. }
  29. // 把整数 n 格式化成 4 字节的网络字节序
  30. func encodeNetworkBytesOrder(orderBytes []byte, n int) {
  31. if len(orderBytes) != 4 {
  32. panic("the length of orderBytes must be equal to 4")
  33. }
  34. orderBytes[0] = byte(n >> 24)
  35. orderBytes[1] = byte(n >> 16)
  36. orderBytes[2] = byte(n >> 8)
  37. orderBytes[3] = byte(n)
  38. }
  39. // 从 4 字节的网络字节序里解析出整数
  40. func decodeNetworkBytesOrder(orderBytes []byte) (n int) {
  41. if len(orderBytes) != 4 {
  42. panic("the length of orderBytes must be equal to 4")
  43. }
  44. n = int(orderBytes[0])<<24 |
  45. int(orderBytes[1])<<16 |
  46. int(orderBytes[2])<<8 |
  47. int(orderBytes[3])
  48. return
  49. }
  50. //AESEncryptMsg encryptedMsg = AES_Encrypt[random(16B) + msg_len(4B) + rawXMLMsg + AppId]
  51. func AESEncryptMsg(random, rawXMLMsg []byte, AppId string, AESKey [32]byte) (encryptedMsg []byte) {
  52. const BLOCK_SIZE = 32 // PKCS#7
  53. buf := make([]byte, 20+len(rawXMLMsg)+len(AppId)+BLOCK_SIZE)
  54. plain := buf[:20]
  55. pad := buf[len(buf)-BLOCK_SIZE:]
  56. // 拼接
  57. copy(plain, random)
  58. encodeNetworkBytesOrder(plain[16:20], len(rawXMLMsg))
  59. plain = append(plain, rawXMLMsg...)
  60. plain = append(plain, AppId...)
  61. // PKCS#7 补位
  62. amountToPad := BLOCK_SIZE - len(plain)%BLOCK_SIZE
  63. for i := 0; i < amountToPad; i++ {
  64. pad[i] = byte(amountToPad)
  65. }
  66. plain = buf[:len(plain)+amountToPad]
  67. // 加密
  68. block, err := aes.NewCipher(AESKey[:])
  69. if err != nil {
  70. panic(err)
  71. }
  72. mode := cipher.NewCBCEncrypter(block, AESKey[:16])
  73. mode.CryptBlocks(plain, plain)
  74. encryptedMsg = plain
  75. return
  76. }
  77. // encryptedMsg = AES_Encrypt[random(16B) + msg_len(4B) + rawXMLMsg + AppId]
  78. func AESDecryptMsg(encryptedMsg []byte, AppId string, AESKey [32]byte) (random, rawXMLMsg []byte, err error) {
  79. const BLOCK_SIZE = 32 // PKCS#7
  80. if len(encryptedMsg) < BLOCK_SIZE {
  81. err = fmt.Errorf("the length of encryptedMsg too short: %d", len(encryptedMsg))
  82. return
  83. }
  84. if len(encryptedMsg)%BLOCK_SIZE != 0 {
  85. err = fmt.Errorf("encryptedMsg is not a multiple of the block size, the length is %d", len(encryptedMsg))
  86. return
  87. }
  88. plain := make([]byte, len(encryptedMsg)) // len(plain) >= BLOCK_SIZE
  89. // 解密
  90. block, err := aes.NewCipher(AESKey[:])
  91. if err != nil {
  92. panic(err)
  93. }
  94. mode := cipher.NewCBCDecrypter(block, AESKey[:16])
  95. mode.CryptBlocks(plain, encryptedMsg)
  96. // PKCS#7 去除补位
  97. amountToPad := int(plain[len(plain)-1])
  98. if amountToPad < 1 || amountToPad > BLOCK_SIZE {
  99. err = fmt.Errorf("the amount to pad is invalid: %d", amountToPad)
  100. return
  101. }
  102. plain = plain[:len(plain)-amountToPad]
  103. // 反拼装
  104. // len(plain) == 16+4+len(rawXMLMsg)+len(AppId)
  105. // len(AppId) > 0
  106. if len(plain) <= 20 {
  107. err = fmt.Errorf("plain msg too short, the length is %d", len(plain))
  108. return
  109. }
  110. msgLen := decodeNetworkBytesOrder(plain[16:20])
  111. if msgLen < 0 {
  112. err = fmt.Errorf("invalid msg length: %d", msgLen)
  113. return
  114. }
  115. msgEnd := 20 + msgLen
  116. if len(plain) <= msgEnd {
  117. err = fmt.Errorf("msg length too large: %d", msgLen)
  118. return
  119. }
  120. AppIdHave := string(plain[msgEnd:])
  121. if AppIdHave != AppId { // crypto/subtle.ConstantTimeCompare ???
  122. err = fmt.Errorf("AppId mismatch, have: %s, want: %s", AppIdHave, AppId)
  123. return
  124. }
  125. random = plain[:16:16]
  126. rawXMLMsg = plain[20:msgEnd]
  127. return
  128. }