go 语言实现AES大量文本加密解密
原文地址: https://nages.cc/archives/1690558621083
因为AES加密算法一次只能加密16个字符, 所以超过16个就需要分批次加密, 以下是本人实现的分批次加密
密钥对齐
将密钥的长度对齐至16, 24, 32位
// fix AES Key
func checkKeyAES(key string) (cipher.Block, error) {
keyLen := len(key)
if keyLen <= 32 {
if keyLen <= 16 {
for i := 0; i < 16-keyLen; i++ {
key += "0"
}
} else if keyLen <= 24 {
for i := 0; i < 24-keyLen; i++ {
key += "0"
}
} else if keyLen <= 32 {
for i := 0; i < 32-keyLen; i++ {
key += "0"
}
}
} else {
return nil, errors.New("key len is max 32 size")
}
return aes.NewCipher([]byte(key))
}
加密
实现大量文本的加密, 少量也可使用
// EncryptAES AES 加密字符串, key最长32位. 不足位数补充0
func EncryptAES(key string, plaintext string) (string, error) {
c, err := checkKeyAES(key)
if err != nil {
return "", err
}
plaintextBytes := []byte(plaintext)
plaintextLen := len(plaintextBytes)
if plaintextLen <= 16 {
out := make([]byte, 16)
c.Encrypt(out, plaintextBytes)
return hex.EncodeToString(out), nil
} else {
// aes一次只能加密16字节, 超过16字节只能分批加密
fetch := plaintextLen/16 + 1
rs := ""
for fetch > 0 {
if fetch == 1 {
out := make([]byte, 16)
out2 := make([]byte, 16-plaintextLen)
plaintextBytes = append(plaintextBytes, out2...)
c.Encrypt(out, plaintextBytes)
rs += hex.EncodeToString(out)
} else {
out := make([]byte, 16)
c.Encrypt(out, plaintextBytes[:16])
rs += hex.EncodeToString(out)
plaintextBytes = plaintextBytes[16:]
}
plaintextLen -= 16
fetch -= 1
}
return rs, nil
}
}
解密
实现大量文本的解密, 少量也可使用
// DecryptAES 解密文本
func DecryptAES(key string, encryptText string) (string, error) {
cipher1, err := checkKeyAES(key)
if err != nil {
return "", err
}
decodeText, _ := hex.DecodeString(encryptText)
encryptTextLen := len(decodeText)
if encryptTextLen <= 16 {
out := make([]byte, encryptTextLen)
cipher1.Decrypt(out, decodeText)
return string(out[:]), nil
} else {
fetch := encryptTextLen / 16
rs := make([]byte, 0)
for fetch > 0 {
if fetch == 1 {
out := make([]byte, 16)
decodeText = append(decodeText, make([]byte, 16-encryptTextLen)...)
cipher1.Decrypt(out, decodeText)
rs = append(rs, out...)
} else {
out := make([]byte, 16)
cipher1.Decrypt(out, decodeText[:16])
rs = append(rs, out...)
decodeText = decodeText[16:]
}
encryptTextLen -= 16
fetch -= 1
}
return string(rs), err
}
}
总体实现
package utils
import (
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"errors"
)
// EncryptAES AES 加密字符串, key最长32位. 不足位数补充0
func EncryptAES(key string, plaintext string) (string, error) {
c, err := checkKeyAES(key)
if err != nil {
return "", err
}
plaintextBytes := []byte(plaintext)
plaintextLen := len(plaintextBytes)
if plaintextLen <= 16 {
out := make([]byte, 16)
c.Encrypt(out, plaintextBytes)
return hex.EncodeToString(out), nil
} else {
// aes一次只能加密16字节, 超过16字节只能分批加密
fetch := plaintextLen/16 + 1
rs := ""
for fetch > 0 {
if fetch == 1 {
out := make([]byte, 16)
out2 := make([]byte, 16-plaintextLen)
plaintextBytes = append(plaintextBytes, out2...)
c.Encrypt(out, plaintextBytes)
rs += hex.EncodeToString(out)
} else {
out := make([]byte, 16)
c.Encrypt(out, plaintextBytes[:16])
rs += hex.EncodeToString(out)
plaintextBytes = plaintextBytes[16:]
}
plaintextLen -= 16
fetch -= 1
}
return rs, nil
}
}
// DecryptAES 解密文本
func DecryptAES(key string, encryptText string) (string, error) {
cipher1, err := checkKeyAES(key)
if err != nil {
return "", err
}
decodeText, _ := hex.DecodeString(encryptText)
encryptTextLen := len(decodeText)
if encryptTextLen <= 16 {
out := make([]byte, encryptTextLen)
cipher1.Decrypt(out, decodeText)
return string(out[:]), nil
} else {
fetch := encryptTextLen / 16
rs := make([]byte, 0)
for fetch > 0 {
if fetch == 1 {
out := make([]byte, 16)
decodeText = append(decodeText, make([]byte, 16-encryptTextLen)...)
cipher1.Decrypt(out, decodeText)
rs = append(rs, out...)
} else {
out := make([]byte, 16)
cipher1.Decrypt(out, decodeText[:16])
rs = append(rs, out...)
decodeText = decodeText[16:]
}
encryptTextLen -= 16
fetch -= 1
}
return string(rs), err
}
}
// fix AES Key
func checkKeyAES(key string) (cipher.Block, error) {
keyLen := len(key)
if keyLen <= 32 {
if keyLen <= 16 {
for i := 0; i < 16-keyLen; i++ {
key += "0"
}
} else if keyLen <= 24 {
for i := 0; i < 24-keyLen; i++ {
key += "0"
}
} else if keyLen <= 32 {
for i := 0; i < 32-keyLen; i++ {
key += "0"
}
}
} else {
return nil, errors.New("key len is max 32 size")
}
return aes.NewCipher([]byte(key))
}
测试
package main
import (
"fmt"
"go_utils/utils"
)
func 测试加密() {
key := "1111111111111111111111"
value := "This is a secret:123456, 这是一段中文文本"
fmt.Println("key", key)
fmt.Println("value", value)
fmt.Println("=======================================================")
//value = base64.StdEncoding.EncodeToString([]byte(value))
fmt.Println(value)
aes, err := utils.EncryptAES(key, value)
if err != nil {
panic(err)
}
fmt.Println(aes)
encryptAES, err := utils.DecryptAES(key, aes)
if err != nil {
panic(err)
}
fmt.Println(encryptAES)
}
func main() {
测试加密()
}
测试截图
