xlog_encrypt.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package xlog
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "errors"
  6. "fmt"
  7. )
  8. // 外部禁止使用此结构体创建实例,否则会出错
  9. type XlogEncrypt struct {
  10. AesIv []byte // 长度必须为aes.BlockSize
  11. }
  12. var aes_key = []byte("12369854712564897564325467553685") // 32 字节 = 256 位
  13. var aes_iv = []byte("5123688955621365")
  14. // 必须用函数创建实例,否则会出错
  15. func NewXlogEncrypt() XlogEncrypt {
  16. xe := XlogEncrypt{
  17. AesIv: aes_iv,
  18. }
  19. return xe
  20. }
  21. func (x *XlogEncrypt) SetNewIv(newIv []byte) error {
  22. if len(newIv) != aes.BlockSize {
  23. return fmt.Errorf("IV length must be 16 bytes, got %d", len(newIv))
  24. }
  25. x.AesIv = newIv
  26. return nil
  27. }
  28. // PKCS7 填充
  29. func PKCS7Pad(data []byte, blockSize int) []byte {
  30. padLen := blockSize - len(data)%blockSize
  31. pad := make([]byte, padLen)
  32. for i := range pad {
  33. pad[i] = byte(padLen)
  34. }
  35. return append(data, pad...)
  36. }
  37. // PKCS7 去填充
  38. func PKCS7Unpad(data []byte, blockSize int) ([]byte, error) {
  39. length := len(data)
  40. if length == 0 {
  41. return nil, errors.New("data is empty")
  42. }
  43. if length%blockSize != 0 {
  44. return nil, errors.New("data is not a multiple of block size")
  45. }
  46. padLen := int(data[length-1])
  47. if padLen == 0 || padLen > blockSize {
  48. return nil, errors.New("invalid padding")
  49. }
  50. for i := 0; i < padLen; i++ {
  51. if data[length-1-i] != byte(padLen) {
  52. return nil, errors.New("invalid padding")
  53. }
  54. }
  55. return data[:length-padLen], nil
  56. }
  57. // AES-256-CBC 加密
  58. func Aes256CbcEncrypt(plainText, iv []byte) ([]byte, error) {
  59. if len(aes_key) != 32 {
  60. return nil, errors.New("key length must be 32 bytes")
  61. }
  62. if len(iv) != aes.BlockSize {
  63. return nil, errors.New("IV length must be 16 bytes")
  64. }
  65. block, err := aes.NewCipher(aes_key)
  66. if err != nil {
  67. return nil, err
  68. }
  69. // PKCS7 填充
  70. padded := PKCS7Pad(plainText, aes.BlockSize)
  71. cipherText := make([]byte, len(padded))
  72. mode := cipher.NewCBCEncrypter(block, iv)
  73. mode.CryptBlocks(cipherText, padded)
  74. return cipherText, nil
  75. }
  76. // AES-256-CBC 解密
  77. func Aes256CbcDecrypt(cipherText []byte, iv []byte) ([]byte, error) {
  78. if len(aes_key) != 32 {
  79. return nil, errors.New("key length must be 32 bytes")
  80. }
  81. if len(iv) != aes.BlockSize {
  82. return nil, errors.New("IV length must be 16 bytes")
  83. }
  84. block, err := aes.NewCipher(aes_key)
  85. if err != nil {
  86. return nil, err
  87. }
  88. if len(cipherText)%aes.BlockSize != 0 {
  89. return nil, fmt.Errorf("cipherText is not a multiple of the block size")
  90. }
  91. mode := cipher.NewCBCDecrypter(block, iv)
  92. plaintext := make([]byte, len(cipherText))
  93. mode.CryptBlocks(plaintext, cipherText)
  94. // 去掉 PKCS7 填充
  95. plaintext, err = PKCS7Unpad(plaintext, aes.BlockSize)
  96. if err != nil {
  97. return nil, err
  98. }
  99. return plaintext, nil
  100. }
  101. // 加密数据
  102. func (x XlogEncrypt) EncryptData(data []byte) ([]byte, error) {
  103. fmt.Println("NewIv")
  104. fmt.Println(x.AesIv)
  105. encrypted, err := Aes256CbcEncrypt(data, x.AesIv)
  106. if err != nil {
  107. return nil, err
  108. }
  109. return encrypted, nil
  110. }
  111. // 解密数据
  112. func (x XlogEncrypt) DecryptData(data []byte) ([]byte, error) {
  113. decrypted, err := Aes256CbcDecrypt(data, x.AesIv)
  114. if err != nil {
  115. return nil, err
  116. }
  117. return decrypted, nil
  118. }