msg_encrypt.go 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /**
  2. * Copyright (c) 2022 Yansen Zhang
  3. * wxcomponent is licensed under Mulan PSL v2.
  4. * You can use this software according to the terms and conditions of the Mulan PSL v2.
  5. * You may obtain a copy of Mulan PSL v2 at:
  6. * http://license.coscl.org.cn/MulanPSL2
  7. * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
  8. * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
  9. * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
  10. * See the Mulan PSL v2 for more details.
  11. **/
  12. package encrypt
  13. import (
  14. "bytes"
  15. "crypto/aes"
  16. "crypto/cipher"
  17. "encoding/base64"
  18. "errors"
  19. )
  20. // MsgEncode 使用 AES CBC 模式加密数据
  21. // data 为待加密数据
  22. func MsgEncode(data []byte, encodingAESKey, iv string) ([]byte, error) {
  23. if encodingAESKey == "" {
  24. return nil, errors.New("加密 EncodingAESKey 为空")
  25. }
  26. if iv == "" {
  27. return nil, errors.New("加密 IV 为空")
  28. }
  29. if nil == data || len(data) == 0 {
  30. return nil, errors.New("待加密 消息 为空")
  31. }
  32. aesKey, e1 := base64.StdEncoding.DecodeString(encodingAESKey + "=")
  33. if e1 != nil {
  34. return nil, e1
  35. }
  36. block, e2 := aes.NewCipher(aesKey)
  37. if e2 != nil {
  38. return nil, e2
  39. }
  40. blockSize := block.BlockSize()
  41. dist := pkcs7(data, blockSize)
  42. // CBC
  43. mode := cipher.NewCBCEncrypter(block, []byte(iv))
  44. mode.CryptBlocks(dist, data)
  45. // 如果需要拿到字符串, 请使用
  46. // fmt.Sprintf("%x", xxx)
  47. // 或者使用 base64 转码
  48. return dist, nil
  49. }
  50. // MsgDecode 是 MsgEncode 的反操作, 用来解密数据
  51. // data 为待解密数据
  52. func MsgDecode(data []byte, encodingAESKey, iv string) ([]byte, error) {
  53. if encodingAESKey == "" {
  54. return nil, errors.New("解密 EncodingAESKey 为空")
  55. }
  56. if iv == "" {
  57. return nil, errors.New("解密 IV 为空")
  58. }
  59. if nil == data || len(data) == 0 {
  60. return nil, errors.New("待解密 消息 为空")
  61. }
  62. aesKey, e1 := base64.StdEncoding.DecodeString(encodingAESKey + "=")
  63. if e1 != nil {
  64. return nil, e1
  65. }
  66. block, err := aes.NewCipher(aesKey)
  67. if err != nil {
  68. return nil, err
  69. }
  70. dist := make([]byte, len(data))
  71. mode := cipher.NewCBCDecrypter(block, []byte(iv))
  72. mode.CryptBlocks(dist, data)
  73. // 如果需要拿到字符串, 请使用
  74. // fmt.Sprintf("%s", xxx)
  75. return unpkcs7(dist), nil
  76. }
  77. // pkcs7 填充
  78. func pkcs7(data []byte, blockSize int) []byte {
  79. paddingBlock := blockSize - len(data)%blockSize
  80. if paddingBlock == 0 {
  81. paddingBlock = blockSize
  82. }
  83. padding := bytes.Repeat([]byte{byte(paddingBlock)}, paddingBlock)
  84. return append(data, padding...)
  85. }
  86. // unpkcs7 取消 pkcs7 填充
  87. func unpkcs7(data []byte) []byte {
  88. length := len(data)
  89. unpadding := int(data[length-1])
  90. return data[:(length - unpadding)]
  91. }