mcrypto.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. package packet
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "crypto/des"
  7. "encoding/binary"
  8. "encoding/hex"
  9. "errors"
  10. )
  11. const AESKey = "F7A72DE7D6264530F01BA49BC73EB873"
  12. const macKey = "B0FB83E39A5EBFAABE471362A58393FF"
  13. const macIV = "D951DBE037C82325"
  14. func Encrypt(plaintext []byte, keyHex string, isPacket50 bool) ([]byte, error) {
  15. key := []byte(keyHex)
  16. // 构建密文结构体: 4 byte 明文长度+密文+8 byte MAC检验码
  17. result := []byte{}
  18. // 明文长度
  19. plaintextLen := len(plaintext)
  20. plaintextLenData := make([]byte, 4) // 如果写为 []byte{},PutUint32时会报溢出
  21. binary.LittleEndian.PutUint32(plaintextLenData, uint32(plaintextLen))
  22. result = append(result, plaintextLenData...)
  23. // mac校验目标
  24. macPlainText := result[:]
  25. macPlainText = append(macPlainText, []byte{0, 0, 0, 0}...)
  26. // 对内容进行加密
  27. if isPacket50 {
  28. // 5.0 报文
  29. ciphertext, err := aesEncrypt(plaintext, key)
  30. // ciphertext, err := aesEncrypt(plaintext, key)
  31. if err != nil {
  32. return nil, err
  33. }
  34. result = append(result, ciphertext...)
  35. } else {
  36. // 4.0 报文
  37. }
  38. // MAC检验码
  39. // 注意:由于服务端的错误(遇到\0就停止),原本需要把长度+密文生成校验码,现改由长度4 byte进行校验即可
  40. macKeyData, _ := hex.DecodeString(macKey)
  41. macIVData, _ := hex.DecodeString(macIV)
  42. macData, err := macAnsi(macPlainText, macKeyData, macIVData)
  43. if err != nil {
  44. return nil, err
  45. }
  46. result = append(result, macData...)
  47. return result, nil
  48. }
  49. func Decrypt(ciphertext []byte, keyHex string, isPacket50 bool) ([]byte, error) {
  50. key := []byte(keyHex)
  51. // 对内容进行加密
  52. if isPacket50 {
  53. return aesDecrypt(ciphertext, key)
  54. } else {
  55. return nil, nil
  56. }
  57. }
  58. func aesEncrypt(plaintext, key []byte) ([]byte, error) {
  59. block, err := aes.NewCipher(key)
  60. if err != nil {
  61. return nil, errors.New("错误的数据或密钥")
  62. }
  63. ecb := NewECBEncrypter(block)
  64. content := plaintext[:]
  65. content = PKCS5Padding(content, block.BlockSize())
  66. crypted := make([]byte, len(content))
  67. ecb.CryptBlocks(crypted, content)
  68. return crypted, nil
  69. }
  70. func aesDecrypt(crypted, key []byte) ([]byte, error) {
  71. block, err := aes.NewCipher(key)
  72. if err != nil {
  73. return nil, errors.New("错误的数据或密钥")
  74. }
  75. blockMode := NewECBDecrypter(block)
  76. origData := make([]byte, len(crypted))
  77. blockMode.CryptBlocks(origData, crypted)
  78. origData = PKCS5UnPadding(origData)
  79. return origData, nil
  80. }
  81. // Des加密
  82. func desEncrypt(plaintext []byte, key []byte) ([]byte, error) {
  83. if len(plaintext) < 1 || len(key) < 1 {
  84. return nil, errors.New("错误的数据或密钥")
  85. }
  86. block, err := des.NewCipher(key)
  87. if err != nil {
  88. return nil, err
  89. }
  90. blockSize := block.BlockSize()
  91. origData := PKCS5Padding(plaintext, blockSize)
  92. out := make([]byte, len(origData))
  93. dst := out
  94. // for len(origData) > 0 {
  95. // block.Encrypt(dst, origData[:blockSize])
  96. // origData = origData[blockSize:]
  97. // dst = dst[blockSize:]
  98. // }
  99. // return out, nil
  100. block.Encrypt(dst, origData[:blockSize])
  101. origData = origData[blockSize:]
  102. dst = dst[blockSize:]
  103. return out[0:8], nil
  104. }
  105. // Des解密
  106. func desDecrypt(plaintext []byte, key []byte) ([]byte, error) {
  107. if len(plaintext) < 1 || len(key) < 1 {
  108. return nil, errors.New("wrong data or key")
  109. }
  110. block, err := des.NewCipher(key)
  111. if err != nil {
  112. return nil, err
  113. }
  114. blockSize := block.BlockSize()
  115. origData := PKCS5Padding(plaintext, blockSize)
  116. out := make([]byte, len(origData))
  117. dst := out
  118. // for len(origData) > 0 {
  119. // block.Decrypt(dst, origData[:blockSize])
  120. // origData = origData[blockSize:]
  121. // dst = dst[blockSize:]
  122. // }
  123. // return out, nil
  124. block.Decrypt(dst, origData[:blockSize])
  125. origData = origData[blockSize:]
  126. dst = dst[blockSize:]
  127. return out[0:8], nil
  128. }
  129. func macAnsiX99(plainText []byte, key []byte, iv []byte) ([]byte, error) {
  130. if len(plainText)%8 != 0 {
  131. return nil, errors.New("目标数据长度必须为8的整数倍")
  132. }
  133. if len(key) != 8 {
  134. return nil, errors.New("密钥位数不正确")
  135. }
  136. if len(iv) != 8 {
  137. return nil, errors.New("向量位数不正确")
  138. }
  139. macData := iv[:]
  140. xorData := make([]byte, 8)
  141. for i := 0; i < len(plainText); i += 8 {
  142. // 以8 byte为单位进行异或运算
  143. for j := 0; j < 8; j++ {
  144. xorData[j] = macData[j] ^ plainText[i+j]
  145. }
  146. // 异或结果的 8 byte 数据进行一次DES加密
  147. desData, err := desEncrypt(xorData, key)
  148. if err != nil {
  149. return nil, err
  150. }
  151. macData = desData[:]
  152. }
  153. return macData, nil
  154. }
  155. func macAnsiX919(plainText []byte, key []byte, iv []byte) ([]byte, error) {
  156. if len(plainText)%8 != 0 {
  157. return nil, errors.New("目标数据长度必须为8的整数倍")
  158. }
  159. if len(key) != 16 {
  160. return nil, errors.New("密钥位数不正确")
  161. }
  162. if len(iv) != 8 {
  163. return nil, errors.New("向量位数不正确")
  164. }
  165. // 分解密钥
  166. keyLeft := key[0:8]
  167. keyRight := key[8:16]
  168. // MAC(L)->R解密->L加密
  169. dataLeft, err := macAnsiX99(plainText, keyLeft, iv)
  170. if err != nil {
  171. return nil, err
  172. }
  173. dataRight, err := desDecrypt(dataLeft, keyRight)
  174. if err != nil {
  175. return nil, err
  176. }
  177. return desEncrypt(dataRight, keyLeft)
  178. }
  179. func macAnsi(plainText []byte, key []byte, iv []byte) ([]byte, error) {
  180. keyLen := len(key)
  181. if keyLen == 8 {
  182. return macAnsiX99(plainText, key, iv)
  183. } else if keyLen == 16 {
  184. return macAnsiX919(plainText, key, iv)
  185. } else {
  186. return nil, errors.New("密钥位数不正确")
  187. }
  188. }
  189. //ECB PKCS5Padding
  190. func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
  191. padding := blockSize - len(ciphertext)%blockSize
  192. padtext := bytes.Repeat([]byte{byte(padding)}, padding)
  193. return append(ciphertext, padtext...)
  194. }
  195. //ECB PKCS5Unpadding
  196. func PKCS5UnPadding(origData []byte) []byte {
  197. length := len(origData)
  198. // 去掉最后一个字节 unpadding 次
  199. unpadding := int(origData[length-1])
  200. if unpadding > unpadding {
  201. return []byte{}
  202. }
  203. return origData[:(length - unpadding)]
  204. }
  205. type ecb struct {
  206. b cipher.Block
  207. blockSize int
  208. }
  209. func newECB(b cipher.Block) *ecb {
  210. return &ecb{
  211. b: b,
  212. blockSize: b.BlockSize(),
  213. }
  214. }
  215. type ecbEncrypter ecb
  216. // NewECBEncrypter returns a BlockMode which encrypts in electronic code book
  217. // mode, using the given Block.
  218. func NewECBEncrypter(b cipher.Block) cipher.BlockMode {
  219. return (*ecbEncrypter)(newECB(b))
  220. }
  221. func (x *ecbEncrypter) BlockSize() int { return x.blockSize }
  222. func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
  223. if len(src)%x.blockSize != 0 {
  224. panic("crypto/cipher: input not full blocks")
  225. }
  226. if len(dst) < len(src) {
  227. panic("crypto/cipher: output smaller than input")
  228. }
  229. for len(src) > 0 {
  230. x.b.Encrypt(dst, src[:x.blockSize])
  231. src = src[x.blockSize:]
  232. dst = dst[x.blockSize:]
  233. }
  234. }
  235. type ecbDecrypter ecb
  236. // NewECBDecrypter returns a BlockMode which decrypts in electronic code book
  237. // mode, using the given Block.
  238. func NewECBDecrypter(b cipher.Block) cipher.BlockMode {
  239. return (*ecbDecrypter)(newECB(b))
  240. }
  241. func (x *ecbDecrypter) BlockSize() int { return x.blockSize }
  242. func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
  243. if len(src)%x.blockSize != 0 {
  244. panic("crypto/cipher: input not full blocks")
  245. }
  246. if len(dst) < len(src) {
  247. panic("crypto/cipher: output smaller than input")
  248. }
  249. for len(src) > 0 {
  250. x.b.Decrypt(dst, src[:x.blockSize])
  251. src = src[x.blockSize:]
  252. dst = dst[x.blockSize:]
  253. }
  254. }