package aesx import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/hex" "errors" "fmt" "io" "strings" ) // AES-256-ECB 加密,返回大写的十六进制字符串 func EncryptECBHex(input, key string) (string, error) { // 创建AES加密器 block, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } // 对输入数据进行PKCS7填充 paddedInput := PKCS7Padding([]byte(input), block.BlockSize()) // ECB模式加密 encrypted := make([]byte, len(paddedInput)) for i := 0; i < len(paddedInput); i += aes.BlockSize { block.Encrypt(encrypted[i:i+aes.BlockSize], paddedInput[i:i+aes.BlockSize]) } // 转换为十六进制并大写 result := hex.EncodeToString(encrypted) return strings.ToUpper(result), nil } // AES-256-ECB 解密,输入大写的十六进制字符串 func DecryptECBHex(encryptedHex, key string) (string, error) { encrypted, err := hex.DecodeString(encryptedHex) if err != nil { return "", fmt.Errorf("hex解码失败: %v", err) } block, err := aes.NewCipher([]byte(key)) if err != nil { return "", fmt.Errorf("创建AES解密器失败: %v", err) } // ECB模式解密 decrypted := make([]byte, len(encrypted)) for i := 0; i < len(encrypted); i += aes.BlockSize { block.Decrypt(decrypted[i:i+aes.BlockSize], encrypted[i:i+aes.BlockSize]) } // 去除PKCS7填充 unpaddedData, err := PKCS7UnPadding(decrypted) if err != nil { return "", fmt.Errorf("去除填充失败: %v", err) } return string(unpaddedData), nil } // AES-256-CBC 加密 func EncryptCBCHex(plaintext, key string) (string, error) { block, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } blockSize := block.BlockSize() plainBytes := PKCS7Padding([]byte(plaintext), blockSize) // 创建密文字节切片,包含IV空间 cipherbyte := make([]byte, aes.BlockSize+len(plainBytes)) // 生成随机IV iv := cipherbyte[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } // 创建CBC模式加密器 blockMode := cipher.NewCBCEncrypter(block, iv) // 加密数据 blockMode.CryptBlocks(cipherbyte[aes.BlockSize:], plainBytes) // 转换为十六进制并大写 result := hex.EncodeToString(cipherbyte) return strings.ToUpper(result), nil } // AES-256-CBC 解密 func DecryptCBCHex(encryptedHex, key string) (string, error) { cipherbyte, err := hex.DecodeString(encryptedHex) if err != nil { return "", fmt.Errorf("hex解码失败: %v", err) } if len(cipherbyte) < aes.BlockSize { return "", errors.New("ciphertext too short") } block, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } iv := cipherbyte[:aes.BlockSize] cipherbyte = cipherbyte[aes.BlockSize:] if len(cipherbyte)%aes.BlockSize != 0 { return "", errors.New("ciphertext is not a multiple of the block size") } blockMode := cipher.NewCBCDecrypter(block, iv) origData := make([]byte, len(cipherbyte)) blockMode.CryptBlocks(origData, cipherbyte) origBy, err := PKCS7UnPadding(origData) if err != nil { return "", err } return string(origBy), nil } /* AES CBC 加密 key:加密key plaintext:加密明文 ciphertext:解密返回字节字符串[ 整型以十六进制方式显示] */ func AESCBCEncrypt(key, plaintext string) (ciphertext string, err error) { block, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } padding := aes.BlockSize - (len(plaintext) % aes.BlockSize) padtest := bytes.Repeat([]byte{byte(padding)}, padding) plainBytes := append([]byte(plaintext), padtest...) cipherbyte := make([]byte, aes.BlockSize+len(plainBytes)) iv := cipherbyte[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } mode := cipher.NewCBCEncrypter(block, iv) mode.CryptBlocks(cipherbyte[aes.BlockSize:], plainBytes) ciphertext = fmt.Sprintf("%x\n", cipherbyte) return } // AES CBC 解码 // key:解密key // ciphertext:加密返回的串 // plaintext:解密后的字符串 func AESCBCDecrypter(key, ciphertext string) (plaintext string, err error) { cipherbyte, _ := hex.DecodeString(ciphertext) keybyte := []byte(key) block, err := aes.NewCipher(keybyte) if err != nil { return "", err } if len(cipherbyte) < aes.BlockSize { return "", errors.New("ciphertext too short") } iv := cipherbyte[:aes.BlockSize] cipherbyte = cipherbyte[aes.BlockSize:] if len(cipherbyte)%aes.BlockSize != 0 { return "", errors.New("ciphertext is not a multiple of the block size") } mode := cipher.NewCBCDecrypter(block, iv) mode.CryptBlocks(cipherbyte, cipherbyte) //fmt.Printf("%s\n", ciphertext) plaintext = string(cipherbyte[:]) return } // AES GCM 加密 // key:加密key // plaintext:加密明文 // ciphertext:解密返回字节字符串[ 整型以十六进制方式显示] func EncryptGCM(key, plaintext string) (ciphertext, noncetext string, err error) { plainbyte := []byte(plaintext) keybyte := []byte(key) block, err := aes.NewCipher(keybyte) if err != nil { return "", "", err } // 由于存在重复的风险,请勿使用给定密钥使用超过2^32个随机值。 nonce := make([]byte, 12) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { return "", "", err } aesgcm, err := cipher.NewGCM(block) if err != nil { return "", "", err } cipherbyte := aesgcm.Seal(nil, nonce, plainbyte, nil) ciphertext = fmt.Sprintf("%x\n", cipherbyte) noncetext = fmt.Sprintf("%x\n", nonce) return } // AES GCM 解码 // key:解密key // ciphertext:加密返回的串 // plaintext:解密后的字符串 func DecryptGCM(key, ciphertext, noncetext string) (plaintext string, err error) { cipherbyte, _ := hex.DecodeString(ciphertext) nonce, _ := hex.DecodeString(noncetext) keybyte := []byte(key) block, err := aes.NewCipher(keybyte) if err != nil { return "", err } aesgcm, err := cipher.NewGCM(block) if err != nil { return "", err } plainbyte, err := aesgcm.Open(nil, nonce, cipherbyte, nil) if err != nil { return "", err } //fmt.Printf("%s\n", ciphertext) plaintext = string(plainbyte[:]) return } // AES CFB 加密 func EncryptCFBHex(plaintext, key string) (string, error) { block, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } // 创建密文字节切片,包含IV空间 cipherbyte := make([]byte, aes.BlockSize+len(plaintext)) // 生成随机IV iv := cipherbyte[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } // 创建CFB模式加密器 stream := cipher.NewCFBEncrypter(block, iv) stream.XORKeyStream(cipherbyte[aes.BlockSize:], []byte(plaintext)) // 转换为十六进制并大写 result := hex.EncodeToString(cipherbyte) return strings.ToUpper(result), nil } // AES CFB 解密 func DecryptCFBHex(encryptedHex, key string) (string, error) { cipherbyte, err := hex.DecodeString(encryptedHex) if err != nil { return "", fmt.Errorf("hex解码失败: %v", err) } if len(cipherbyte) < aes.BlockSize { return "", errors.New("ciphertext too short") } block, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } // 获取IV iv := cipherbyte[:aes.BlockSize] cipherbyte = cipherbyte[aes.BlockSize:] // 创建CFB模式解密器 stream := cipher.NewCFBDecrypter(block, iv) stream.XORKeyStream(cipherbyte, cipherbyte) return string(cipherbyte), nil } // AES OFB 加密 func EncryptOFBHex(plaintext, key string) (string, error) { block, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } // 创建密文字节切片,包含IV空间 cipherbyte := make([]byte, aes.BlockSize+len(plaintext)) // 生成随机IV iv := cipherbyte[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } // 创建OFB模式加密器 stream := cipher.NewOFB(block, iv) stream.XORKeyStream(cipherbyte[aes.BlockSize:], []byte(plaintext)) // 转换为十六进制并大写 result := hex.EncodeToString(cipherbyte) return strings.ToUpper(result), nil } // AES OFB 解密 func DecryptOFBHex(encryptedHex, key string) (string, error) { cipherbyte, err := hex.DecodeString(encryptedHex) if err != nil { return "", fmt.Errorf("hex解码失败: %v", err) } if len(cipherbyte) < aes.BlockSize { return "", errors.New("ciphertext too short") } block, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } // 获取IV iv := cipherbyte[:aes.BlockSize] cipherbyte = cipherbyte[aes.BlockSize:] // 创建OFB模式解密器 stream := cipher.NewOFB(block, iv) stream.XORKeyStream(cipherbyte, cipherbyte) return string(cipherbyte), nil } // PKCS7补码 func PKCS7Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } // 去除PKCS7补码 func PKCS7UnPadding(data []byte) ([]byte, error) { length := len(data) if length == 0 { return nil, errors.New("ciphertext is empty") } unpadding := int(data[length-1]) if unpadding > length || unpadding == 0 { return nil, errors.New("unpadding size is invalid") } // 检查填充是否正确 for i := length - unpadding; i < length; i++ { if data[i] != byte(unpadding) { return nil, errors.New("invalid padding") } } return data[:(length - unpadding)], nil }