Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

160 lines
4.0KB

  1. package main
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/rand"
  6. "encoding/base64"
  7. "fmt"
  8. )
  9. var random16 []byte
  10. //Encode convert a xml sequence into encrypted message
  11. func Encode(s string) string {
  12. d := aesEncryptMsg(random16, []byte(s), APIConfig.Appid, getAesEncryptKey())
  13. r := base64.StdEncoding.EncodeToString(d)
  14. fmt.Println(r)
  15. return r
  16. }
  17. //Decode Decode encrypt string to xml context
  18. func Decode(s string) string {
  19. r, _ := base64.StdEncoding.DecodeString(s)
  20. r16, raw, err := aesDecryptMsg([]byte(r), APIConfig.Appid, getAesEncryptKey())
  21. random16 = make([]byte, 16)
  22. copy(random16, r16)
  23. if err == nil {
  24. fmt.Println(string(raw))
  25. return string(raw)
  26. }
  27. return ""
  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. func random16Byte() []byte {
  51. token := make([]byte, 16)
  52. rand.Read(token)
  53. return token
  54. }
  55. //AESEncryptMsg given an xml message and 16 bytes random string
  56. //encryptedMsg = AES_Encrypt[random(16B) + msg_len(4B) + rawXMLMsg + AppId]
  57. func aesEncryptMsg(random, rawXMLMsg []byte, AppId string, AESKey [32]byte) (encryptedMsg []byte) {
  58. const BLOCK_SIZE = 32 // PKCS#7
  59. buf := make([]byte, 20+len(rawXMLMsg)+len(AppId)+BLOCK_SIZE)
  60. plain := buf[:20]
  61. pad := buf[len(buf)-BLOCK_SIZE:]
  62. // 拼接
  63. copy(plain, random)
  64. encodeNetworkBytesOrder(plain[16:20], len(rawXMLMsg))
  65. plain = append(plain, rawXMLMsg...)
  66. plain = append(plain, AppId...)
  67. // PKCS#7 补位
  68. amountToPad := BLOCK_SIZE - len(plain)%BLOCK_SIZE
  69. for i := 0; i < amountToPad; i++ {
  70. pad[i] = byte(amountToPad)
  71. }
  72. plain = buf[:len(plain)+amountToPad]
  73. // 加密
  74. block, err := aes.NewCipher(AESKey[:])
  75. if err != nil {
  76. panic(err)
  77. }
  78. mode := cipher.NewCBCEncrypter(block, AESKey[:16])
  79. mode.CryptBlocks(plain, plain)
  80. encryptedMsg = plain
  81. return
  82. }
  83. //AESDecryptMsg given a string decode it into three parts
  84. // encryptedMsg = AES_Encrypt[random(16B) + msg_len(4B) + rawXMLMsg + AppId]
  85. func aesDecryptMsg(encryptedMsg []byte, AppId string, AESKey [32]byte) (random, rawXMLMsg []byte, err error) {
  86. const BLOCK_SIZE = 32 // PKCS#7
  87. if len(encryptedMsg) < BLOCK_SIZE {
  88. err = fmt.Errorf("the length of encryptedMsg too short: %d", len(encryptedMsg))
  89. return
  90. }
  91. if len(encryptedMsg)%BLOCK_SIZE != 0 {
  92. err = fmt.Errorf("encryptedMsg is not a multiple of the block size, the length is %d", len(encryptedMsg))
  93. return
  94. }
  95. plain := make([]byte, len(encryptedMsg)) // len(plain) >= BLOCK_SIZE
  96. // 解密
  97. block, err := aes.NewCipher(AESKey[:])
  98. if err != nil {
  99. panic(err)
  100. }
  101. mode := cipher.NewCBCDecrypter(block, AESKey[:16])
  102. mode.CryptBlocks(plain, encryptedMsg)
  103. // PKCS#7 去除补位
  104. amountToPad := int(plain[len(plain)-1])
  105. if amountToPad < 1 || amountToPad > BLOCK_SIZE {
  106. err = fmt.Errorf("the amount to pad is invalid: %d", amountToPad)
  107. return
  108. }
  109. plain = plain[:len(plain)-amountToPad]
  110. // 反拼装
  111. // len(plain) == 16+4+len(rawXMLMsg)+len(AppId)
  112. // len(AppId) > 0
  113. if len(plain) <= 20 {
  114. err = fmt.Errorf("plain msg too short, the length is %d", len(plain))
  115. return
  116. }
  117. msgLen := decodeNetworkBytesOrder(plain[16:20])
  118. if msgLen < 0 {
  119. err = fmt.Errorf("invalid msg length: %d", msgLen)
  120. return
  121. }
  122. msgEnd := 20 + msgLen
  123. if len(plain) <= msgEnd {
  124. err = fmt.Errorf("msg length too large: %d", msgLen)
  125. return
  126. }
  127. AppIdHave := string(plain[msgEnd:])
  128. if AppIdHave != AppId { // crypto/subtle.ConstantTimeCompare ???
  129. err = fmt.Errorf("AppId mismatch, have: %s, want: %s", AppIdHave, AppId)
  130. return
  131. }
  132. random = plain[:16:16]
  133. rawXMLMsg = plain[20:msgEnd]
  134. return
  135. }