encryptor.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package encryptor
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "encoding/base64"
  7. "errors"
  8. "fmt"
  9. )
  10. var (
  11. // ErrInvalidBlockSize block size 不合法.
  12. ErrInvalidBlockSize = errors.New("invalid block size")
  13. // ErrInvalidPKCS7Data PKCS7 数据不合法.
  14. ErrInvalidPKCS7Data = errors.New("invalid PKCS7 data")
  15. // ErrInvalidPKCS7Padding padding 不合法.
  16. ErrInvalidPKCS7Padding = errors.New("invalid PKCS7 padding")
  17. )
  18. // Encrypt encrypts plaintext with AES-CBC and returns base64 ciphertext.
  19. func Encrypt(aesKey string, plaintext []byte) (string, error) {
  20. key, err := decodeAESKey(aesKey)
  21. if err != nil {
  22. return "", err
  23. }
  24. block, err := aes.NewCipher(key)
  25. if err != nil {
  26. return "", err
  27. }
  28. plaintext = pkcs7Pad(plaintext, block.BlockSize())
  29. ciphertext := make([]byte, len(plaintext))
  30. mode := cipher.NewCBCEncrypter(block, key[:aes.BlockSize])
  31. mode.CryptBlocks(ciphertext, plaintext)
  32. return base64.StdEncoding.EncodeToString(ciphertext), nil
  33. }
  34. // Decrypt decrypts base64 AES-CBC ciphertext.
  35. func Decrypt(aesKey, ciphertext string) ([]byte, error) {
  36. key, err := decodeAESKey(aesKey)
  37. if err != nil {
  38. return nil, err
  39. }
  40. data, err := base64.StdEncoding.DecodeString(ciphertext)
  41. if err != nil {
  42. return nil, err
  43. }
  44. if len(data) == 0 || len(data)%aes.BlockSize != 0 {
  45. return nil, ErrInvalidPKCS7Data
  46. }
  47. block, err := aes.NewCipher(key)
  48. if err != nil {
  49. return nil, err
  50. }
  51. plaintext := make([]byte, len(data))
  52. mode := cipher.NewCBCDecrypter(block, key[:aes.BlockSize])
  53. mode.CryptBlocks(plaintext, data)
  54. return pkcs7Unpad(plaintext, block.BlockSize())
  55. }
  56. func decodeAESKey(encodingAESKey string) ([]byte, error) {
  57. key, err := base64.StdEncoding.DecodeString(encodingAESKey + "=")
  58. if err != nil {
  59. return nil, err
  60. }
  61. if len(key) != 32 {
  62. return nil, fmt.Errorf("encodingAESKey invalid")
  63. }
  64. return key, nil
  65. }
  66. func pkcs7Pad(data []byte, blockSize int) []byte {
  67. padding := blockSize - len(data)%blockSize
  68. padText := bytes.Repeat([]byte{byte(padding)}, padding)
  69. return append(data, padText...)
  70. }
  71. func pkcs7Unpad(data []byte, blockSize int) ([]byte, error) {
  72. if blockSize <= 0 {
  73. return nil, ErrInvalidBlockSize
  74. }
  75. if len(data) == 0 || len(data)%blockSize != 0 {
  76. return nil, ErrInvalidPKCS7Data
  77. }
  78. padding := int(data[len(data)-1])
  79. if padding == 0 || padding > blockSize || padding > len(data) {
  80. return nil, ErrInvalidPKCS7Padding
  81. }
  82. for i := len(data) - padding; i < len(data); i++ {
  83. if int(data[i]) != padding {
  84. return nil, ErrInvalidPKCS7Padding
  85. }
  86. }
  87. return data[:len(data)-padding], nil
  88. }