Files
packages/tool/aes.go
2025-07-16 18:51:52 +08:00

96 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package tool
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"errors"
"io"
)
// AES加密CBC模式PKCS7填充
func AesEncrypt(data []byte, key []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
// 添加PKCS7填充
data = pkcs7Pad(data, block.BlockSize())
// 创建存储密文的buffer前aes.BlockSize字节存储IV
ciphertext := make([]byte, aes.BlockSize+len(data))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return "", err
}
// CBC加密
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], data)
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// AES解密CBC模式PKCS7填充
func AesDecrypt(encrypted string, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
ciphertext, err := base64.StdEncoding.DecodeString(encrypted)
if err != nil {
return nil, err
}
if len(ciphertext) < aes.BlockSize {
return nil, errors.New("ciphertext too short")
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
if len(ciphertext)%aes.BlockSize != 0 {
return nil, errors.New("ciphertext is not a multiple of the block size")
}
// CBC解密
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(ciphertext, ciphertext)
// 去除PKCS7填充
return pkcs7Unpad(ciphertext)
}
// PKCS7填充
func pkcs7Pad(data []byte, blockSize int) []byte {
padding := blockSize - (len(data) % blockSize)
padText := bytes.Repeat([]byte{byte(padding)}, padding)
return append(data, padText...)
}
// PKCS7去除填充
func pkcs7Unpad(data []byte) ([]byte, error) {
length := len(data)
if length == 0 {
return nil, errors.New("empty input")
}
padding := int(data[length-1])
if padding > length || padding == 0 {
return nil, errors.New("invalid padding")
}
// 验证填充字节是否正确
for i := length - padding; i < length; i++ {
if int(data[i]) != padding {
return nil, errors.New("invalid padding")
}
}
return data[:length-padding], nil
}