package mycrypto import ( "bytes" "crypto/aes" "crypto/cipher" "encoding/hex" "fmt" ) var ( defaultAes256Cbc *Aes256Cbc ) type Aes256Cbc struct { Iv []byte // iv向量 (key 32字节 256位) Key []byte // 加密密钥 (iv 16字节 128位) } func NewAes256Cbc(key, iv string) *Aes256Cbc { if len(key) != 32 { panic("密钥key长度应为32") } if len(iv) != aes.BlockSize { panic("iv长度应为16") } return &Aes256Cbc{ Iv: []byte(iv), Key: []byte(key), } } func InitAes256Cbc(key, iv string) { defaultAes256Cbc = NewAes256Cbc(key, iv) } func Aes256CbcEncrypt(plainText string) (string, error) { return defaultAes256Cbc.Encrypt(plainText) } func Aes256CbcDecrypt(cipherText string) (string, error) { return defaultAes256Cbc.Decrypt(cipherText) } // Encrypt 加密 func (a *Aes256Cbc) Encrypt(plainText string) (res string, err error) { defer func() { if err2 := recover(); err2 != nil { err = fmt.Errorf("panic: %s", err2) } }() // PKCS5填充,补齐数据块 bPlaintext := a.PKCS5Padding([]byte(plainText), aes.BlockSize) block, err := aes.NewCipher(a.Key) if err != nil { return plainText, err } ciphertext := make([]byte, len(bPlaintext)) mode := cipher.NewCBCEncrypter(block, a.Iv) mode.CryptBlocks(ciphertext, bPlaintext) return hex.EncodeToString(ciphertext), nil } // Decrypt 解密 func (a *Aes256Cbc) Decrypt(cipherText string) (res string, err error) { defer func() { if err2 := recover(); err2 != nil { err = fmt.Errorf("panic: %s", err2) } }() block, err := aes.NewCipher(a.Key) if err != nil { return "", err } decodeString, err := hex.DecodeString(cipherText) if err != nil { return "", err } mode := cipher.NewCBCDecrypter(block, a.Iv) mode.CryptBlocks(decodeString, decodeString) // 移除多余填充的补充位 return string(a.PKCS5UnPadding(decodeString)), nil } func (a *Aes256Cbc) PKCS5Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } func (a *Aes256Cbc) PKCS5UnPadding(src []byte) []byte { length := len(src) unpadding := int(src[length-1]) return src[:(length - unpadding)] }