package utils import ( "bytes" "crypto/aes" "crypto/cipher" "fmt" ) func AesEncrypt(rawData, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() rawData = PKCS5Padding(rawData, blockSize) // rawData = ZeroPadding(rawData, block.BlockSize()) blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) encrypted := make([]byte, len(rawData)) // 根据CryptBlocks方法的说明,如下方式初始化encrypted也可以 // encrypted := rawData blockMode.CryptBlocks(encrypted, rawData) return encrypted, nil } func AesDecrypt(encrypted, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) rawData := make([]byte, len(encrypted)) // rawData := encrypted blockMode.CryptBlocks(rawData, encrypted) rawData = PKCS5UnPadding(rawData) // rawData = ZeroUnPadding(rawData) return rawData, nil } func ZeroPadding(cipherText []byte, blockSize int) []byte { padding := blockSize - len(cipherText)%blockSize padText := bytes.Repeat([]byte{0}, padding) return append(cipherText, padText...) } func ZeroUnPadding(rawData []byte) []byte { length := len(rawData) unPadding := int(rawData[length-1]) return rawData[:(length - unPadding)] } func PKCS5Padding(cipherText []byte, blockSize int) []byte { padding := blockSize - len(cipherText)%blockSize padText := bytes.Repeat([]byte{byte(padding)}, padding) return append(cipherText, padText...) } func PKCS5UnPadding(rawData []byte) []byte { length := len(rawData) // 去掉最后一个字节 unPadding 次 unPadding := int(rawData[length-1]) return rawData[:(length - unPadding)] } // 填充0 func zeroFill(key *string) { l := len(*key) if l != 16 && l != 24 && l != 32 { if l < 16 { *key = *key + fmt.Sprintf("%0*d", 16-l, 0) } else if l < 24 { *key = *key + fmt.Sprintf("%0*d", 24-l, 0) } else if l < 32 { *key = *key + fmt.Sprintf("%0*d", 32-l, 0) } else { *key = string([]byte(*key)[:32]) } } } type AesCrypt struct { Key []byte Iv []byte } func (a *AesCrypt) Encrypt(data []byte) ([]byte, error) { aesBlockEncrypt, err := aes.NewCipher(a.Key) if err != nil { println(err.Error()) return nil, err } content := pKCS5Padding(data, aesBlockEncrypt.BlockSize()) cipherBytes := make([]byte, len(content)) aesEncrypt := cipher.NewCBCEncrypter(aesBlockEncrypt, a.Iv) aesEncrypt.CryptBlocks(cipherBytes, content) return cipherBytes, nil } func (a *AesCrypt) Decrypt(src []byte) (data []byte, err error) { decrypted := make([]byte, len(src)) var aesBlockDecrypt cipher.Block aesBlockDecrypt, err = aes.NewCipher(a.Key) if err != nil { println(err.Error()) return nil, err } aesDecrypt := cipher.NewCBCDecrypter(aesBlockDecrypt, a.Iv) aesDecrypt.CryptBlocks(decrypted, src) return pKCS5Trimming(decrypted), nil } func pKCS5Padding(cipherText []byte, blockSize int) []byte { padding := blockSize - len(cipherText)%blockSize padText := bytes.Repeat([]byte{byte(padding)}, padding) return append(cipherText, padText...) } func pKCS5Trimming(encrypt []byte) []byte { padding := encrypt[len(encrypt)-1] return encrypt[:len(encrypt)-int(padding)] }