| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- package encryptor
- import (
- "bytes"
- "crypto/aes"
- "crypto/cipher"
- "encoding/base64"
- "errors"
- "fmt"
- )
- var (
- // ErrInvalidBlockSize block size 不合法.
- ErrInvalidBlockSize = errors.New("invalid block size")
- // ErrInvalidPKCS7Data PKCS7 数据不合法.
- ErrInvalidPKCS7Data = errors.New("invalid PKCS7 data")
- // ErrInvalidPKCS7Padding padding 不合法.
- ErrInvalidPKCS7Padding = errors.New("invalid PKCS7 padding")
- )
- // Encrypt encrypts plaintext with AES-CBC and returns base64 ciphertext.
- func Encrypt(aesKey string, plaintext []byte) (string, error) {
- key, err := decodeAESKey(aesKey)
- if err != nil {
- return "", err
- }
- block, err := aes.NewCipher(key)
- if err != nil {
- return "", err
- }
- plaintext = pkcs7Pad(plaintext, block.BlockSize())
- ciphertext := make([]byte, len(plaintext))
- mode := cipher.NewCBCEncrypter(block, key[:aes.BlockSize])
- mode.CryptBlocks(ciphertext, plaintext)
- return base64.StdEncoding.EncodeToString(ciphertext), nil
- }
- // Decrypt decrypts base64 AES-CBC ciphertext.
- func Decrypt(aesKey, ciphertext string) ([]byte, error) {
- key, err := decodeAESKey(aesKey)
- if err != nil {
- return nil, err
- }
- data, err := base64.StdEncoding.DecodeString(ciphertext)
- if err != nil {
- return nil, err
- }
- if len(data) == 0 || len(data)%aes.BlockSize != 0 {
- return nil, ErrInvalidPKCS7Data
- }
- block, err := aes.NewCipher(key)
- if err != nil {
- return nil, err
- }
- plaintext := make([]byte, len(data))
- mode := cipher.NewCBCDecrypter(block, key[:aes.BlockSize])
- mode.CryptBlocks(plaintext, data)
- return pkcs7Unpad(plaintext, block.BlockSize())
- }
- func decodeAESKey(encodingAESKey string) ([]byte, error) {
- key, err := base64.StdEncoding.DecodeString(encodingAESKey + "=")
- if err != nil {
- return nil, err
- }
- if len(key) != 32 {
- return nil, fmt.Errorf("encodingAESKey invalid")
- }
- return key, nil
- }
- func pkcs7Pad(data []byte, blockSize int) []byte {
- padding := blockSize - len(data)%blockSize
- padText := bytes.Repeat([]byte{byte(padding)}, padding)
- return append(data, padText...)
- }
- func pkcs7Unpad(data []byte, blockSize int) ([]byte, error) {
- if blockSize <= 0 {
- return nil, ErrInvalidBlockSize
- }
- if len(data) == 0 || len(data)%blockSize != 0 {
- return nil, ErrInvalidPKCS7Data
- }
- padding := int(data[len(data)-1])
- if padding == 0 || padding > blockSize || padding > len(data) {
- return nil, ErrInvalidPKCS7Padding
- }
- for i := len(data) - padding; i < len(data); i++ {
- if int(data[i]) != padding {
- return nil, ErrInvalidPKCS7Padding
- }
- }
- return data[:len(data)-padding], nil
- }
|