1. package main
    2. import (
    3. "bytes"
    4. "crypto/aes"
    5. "crypto/cipher"
    6. "encoding/base64"
    7. "fmt"
    8. )
    9. // PKCS7Padding 以块长度的整数倍填充明文
    10. func PKCS7Padding(p []byte, blockSize int) []byte {
    11. pad := blockSize - len(p)%blockSize
    12. padtext := bytes.Repeat([]byte{byte(pad)}, pad)
    13. return append(p, padtext...)
    14. }
    15. // PKCS7UnPadding 从明文的尾部删除填充数据
    16. func PKCS7UnPadding(p []byte) []byte {
    17. length := len(p)
    18. paddLen := int(p[length-1])
    19. return p[:(length - paddLen)]
    20. }
    21. // AESCBCEncrypt 在CBC模式下使用AES算法加密数据
    22. // 注意,要选择AES-128、AES-192或AES-256,密钥长度必须为16、24或32字节
    23. // 注意,AES块大小为16字节
    24. func AESCBCEncrypt(p, key []byte) ([]byte, error) {
    25. block, err := aes.NewCipher(key)
    26. if err != nil {
    27. return nil, err
    28. }
    29. p = PKCS7Padding(p, block.BlockSize())
    30. ciphertext := make([]byte, len(p))
    31. blockMode := cipher.NewCBCEncrypter(block, key[:block.BlockSize()])
    32. blockMode.CryptBlocks(ciphertext, p)
    33. return ciphertext, nil
    34. }
    35. // AESCBCDecrypt :在CBC模式下用AES算法解密密码文本
    36. // 注意,要选择AES-128、AES-192或AES-256,密钥长度必须为16、24或32字节
    37. // 注意,AES块大小为16字节
    38. func _AESCBCDecrypt(c, key []byte) (p []byte, err error) {
    39. defer func() {
    40. if e := recover(); e != nil {
    41. err = fmt.Errorf("err: %v", e)
    42. }
    43. }()
    44. block, err := aes.NewCipher(key)
    45. if err != nil {
    46. return nil, err
    47. }
    48. plaintext := make([]byte, len(c))
    49. blockMode := cipher.NewCBCDecrypter(block, key[:block.BlockSize()])
    50. blockMode.CryptBlocks(plaintext, c)
    51. return _PKCS7UnPadding(plaintext), nil
    52. }
    53. // Base64AESCBCEncrypt 使用CBC模式的AES算法加密数据,并使用base64进行编码
    54. func Base64AESCBCEncrypt(p, key []byte) (string, error) {
    55. c, err := AESCBCEncrypt(p, key)
    56. if err != nil {
    57. return "", err
    58. }
    59. return base64.StdEncoding.EncodeToString(c), nil
    60. }
    61. // Base64AESCBCDecrypt 用CBC模式下的AES算法对base64编码的密码文本进行解密
    62. func Base64AESCBCDecrypt(c string, key []byte) ([]byte, error) {
    63. oriCipher, err := base64.StdEncoding.DecodeString(c)
    64. if err != nil {
    65. return nil, err
    66. }
    67. p, err := AESCBCDecrypt(oriCipher, key)
    68. if err != nil {
    69. return nil, err
    70. }
    71. return p, nil
    72. }
    73. func main() {
    74. p := []byte("plain.text")
    75. key := []byte("OaePr*1tC^cmT@19") // 长度必须为16, 24 or 32
    76. ciphertext, _ := Base64AESCBCEncrypt(p, key)
    77. fmt.Println(ciphertext) // V4vY9maMHw9aCFUIwBJEVQ==
    78. plaintext, _ := Base64AESCBCDecrypt(ciphertext, key)
    79. fmt.Println(string(plaintext)) // plain.text
    80. }