1 Star 0 Fork 0

tuboyou/c2

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
aes.go 7.75 KB
一键复制 编辑 原始数据 按行查看 历史
tuboyou 提交于 2025-03-10 18:02 +08:00 . 添加注释
// Package u2 提供AES加密解密功能,支持ECB和CBC模式,以及PKCS5/PKCS7填充
package u2
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"errors"
)
// PaddingType 定义填充类型常量
type PaddingType int
const (
// PaddingPKCS5 表示使用PKCS5填充,固定块大小为8字节
PaddingPKCS5 PaddingType = iota
// PaddingPKCS7 表示使用PKCS7填充,块大小可变(1-255字节)
PaddingPKCS7
)
// pad 根据指定的填充类型对数据进行填充
//
// 参数:
// - ciphertext: 需要填充的原始数据
// - blockSize: 加密算法的块大小
// - paddingType: 填充类型(PKCS5或PKCS7)
//
// 返回值:
// - []byte: 填充后的数据
func pad(ciphertext []byte, blockSize int, paddingType PaddingType) []byte {
var targetBlockSize int
switch paddingType {
case PaddingPKCS5:
if blockSize != 8 {
panic("PKCS5 padding requires 8-byte block size")
}
targetBlockSize = 8
case PaddingPKCS7:
targetBlockSize = blockSize
default:
targetBlockSize = blockSize
}
padding := targetBlockSize - len(ciphertext)%targetBlockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
// unpad 根据指定的填充类型去除数据中的填充内容
//
// 参数:
// - origData: 需要去除填充的数据
// - paddingType: 填充类型(PKCS5或PKCS7)
//
// 返回值:
// - []byte: 去除填充后的原始数据
func unpad(origData []byte, paddingType PaddingType) []byte {
length := len(origData)
if length == 0 {
return origData
}
unpadding := int(origData[length-1])
// 验证unpadding的有效性
switch paddingType {
case PaddingPKCS5:
if unpadding < 1 || unpadding > 8 {
return origData
}
// 验证所有填充字节是否相同
for i := length - unpadding; i < length; i++ {
if int(origData[i]) != unpadding {
return origData
}
}
case PaddingPKCS7:
if unpadding < 1 || unpadding > length {
return origData
}
// 验证所有填充字节是否相同
for i := length - unpadding; i < length; i++ {
if int(origData[i]) != unpadding {
return origData
}
}
}
return origData[:(length - unpadding)]
}
// validateKey 校验密钥长度,确保密钥长度为16、24或32字节
//
// 参数:
// - key: 待校验的密钥
//
// 返回值:
// - error: 如果密钥长度有效返回nil,否则返回错误
func validateKey(key []byte) error {
switch len(key) {
case 16, 24, 32:
return nil
default:
return errors.New("AES密钥长度必须为128、192或256位(16、24、32字节)")
}
}
// AesEncryptECBWithPadding 使用AES-ECB模式加密数据,并支持选择填充方式
//
// 参数:
// - s: 需要加密的字符串
// - key: 加密密钥
// - paddingType: 填充类型(PKCS5或PKCS7)
//
// 返回值:
// - string: 加密后的Base64编码字符串
// - error: 加密过程中发生的错误
func AesEncryptECBWithPadding(s string, key string, paddingType PaddingType) (string, error) {
if err := validateKey([]byte(key)); err != nil {
return "", err
}
block, err := aes.NewCipher([]byte(key))
if err != nil {
return "", err
}
origData := []byte(s)
blockSize := block.BlockSize()
origData = pad(origData, blockSize, paddingType)
encrypted := make([]byte, len(origData))
// ECB模式加密
for bs, be := 0, blockSize; bs < len(origData); bs, be = bs+blockSize, be+blockSize {
block.Encrypt(encrypted[bs:be], origData[bs:be])
}
return base64.StdEncoding.EncodeToString(encrypted), nil
}
// AesDecryptECBWithPadding 使用AES-ECB模式解密数据,并支持选择填充方式
//
// 参数:
// - s: 需要解密的Base64编码字符串
// - key: 解密密钥
// - paddingType: 填充类型(PKCS5或PKCS7)
//
// 返回值:
// - string: 解密后的原始字符串
// - error: 解密过程中发生的错误
func AesDecryptECBWithPadding(s string, key string, paddingType PaddingType) (string, error) {
if err := validateKey([]byte(key)); err != nil {
return "", err
}
src, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return "", err
}
block, err := aes.NewCipher([]byte(key))
if err != nil {
return "", err
}
blockSize := block.BlockSize()
decrypted := make([]byte, len(src))
// ECB模式解密
for bs, be := 0, blockSize; bs < len(src); bs, be = bs+blockSize, be+blockSize {
block.Decrypt(decrypted[bs:be], src[bs:be])
}
decrypted = unpad(decrypted, paddingType)
return string(decrypted), nil
}
// AesEncryptCBCWithPadding 使用AES-CBC模式加密数据,并支持选择填充方式
//
// 参数:
// - s: 需要加密的字符串
// - key: 加密密钥
// - vi: 初始化向量
// - paddingType: 填充类型(PKCS5或PKCS7)
//
// 返回值:
// - string: 加密后的Base64编码字符串
// - error: 加密过程中发生的错误
func AesEncryptCBCWithPadding(s string, key string, vi string, paddingType PaddingType) (string, error) {
if err := validateKey([]byte(key)); err != nil {
return "", err
}
ekey, err := aes.NewCipher([]byte(key))
if err != nil {
return "", err
}
blockSize := ekey.BlockSize()
origData := []byte(s)
origData = pad(origData, blockSize, paddingType)
blockMode := cipher.NewCBCEncrypter(ekey, []byte(vi))
encrypted := make([]byte, len(origData))
blockMode.CryptBlocks(encrypted, origData)
return base64.StdEncoding.EncodeToString(encrypted), nil
}
// AesDecryptCBCWithPadding 使用AES-CBC模式解密数据,并支持选择填充方式
//
// 参数:
// - s: 需要解密的Base64编码字符串
// - key: 解密密钥
// - vi: 初始化向量
// - paddingType: 填充类型(PKCS5或PKCS7)
//
// 返回值:
// - string: 解密后的原始字符串
// - error: 解密过程中发生的错误
func AesDecryptCBCWithPadding(s string, key string, vi string, paddingType PaddingType) (string, error) {
if err := validateKey([]byte(key)); err != nil {
return "", err
}
src, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return "", err
}
block, err := aes.NewCipher([]byte(key))
if err != nil {
return "", err
}
blockMode := cipher.NewCBCDecrypter(block, []byte(vi))
decrypted := make([]byte, len(src))
blockMode.CryptBlocks(decrypted, src)
decrypted = unpad(decrypted, paddingType)
return string(decrypted), nil
}
// AesEncryptECB 使用AES-ECB模式加密数据,默认使用PKCS7填充
//
// 参数:
// - s: 需要加密的字符串
// - key: 加密密钥
//
// 返回值:
// - string: 加密后的Base64编码字符串
// - error: 加密过程中发生的错误
func AesEncryptECB(s string, key string) (string, error) {
return AesEncryptECBWithPadding(s, key, PaddingPKCS7)
}
// AesDecryptECB 使用AES-ECB模式解密数据,默认使用PKCS7填充
//
// 参数:
// - s: 需要解密的Base64编码字符串
// - key: 解密密钥
//
// 返回值:
// - string: 解密后的原始字符串
// - error: 解密过程中发生的错误
func AesDecryptECB(s string, key string) (string, error) {
return AesDecryptECBWithPadding(s, key, PaddingPKCS7)
}
// AesEncryptCBC 使用AES-CBC模式加密数据,默认使用PKCS7填充
//
// 参数:
// - s: 需要加密的字符串
// - key: 加密密钥
// - vi: 初始化向量
//
// 返回值:
// - string: 加密后的Base64编码字符串
// - error: 加密过程中发生的错误
func AesEncryptCBC(s string, key string, vi string) (string, error) {
return AesEncryptCBCWithPadding(s, key, vi, PaddingPKCS7)
}
// AesDecryptCBC 使用AES-CBC模式解密数据,默认使用PKCS7填充
//
// 参数:
// - s: 需要解密的Base64编码字符串
// - key: 解密密钥
// - vi: 初始化向量
//
// 返回值:
// - string: 解密后的原始字符串
// - error: 解密过程中发生的错误
func AesDecryptCBC(s string, key string, vi string) (string, error) {
return AesDecryptCBCWithPadding(s, key, vi, PaddingPKCS7)
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/tuboyou/c2.git
git@gitee.com:tuboyou/c2.git
tuboyou
c2
c2
v0.0.4

搜索帮助