利用 Go 提供的 AES 加解密与 Base64 编解码包,我们可以轻松实现 AES 加解密。实现之前,首先了解一下 AES 的基本知识。
AES(Advanced Encryption Standard)高级加密标准,是流行的对称加密算法,由美国国家标准与技术研究院(NIST)于 2001 年发布,用于取代 DES。Rijndael 算法 是 AES 标准的一个实现,一般说 AES 指的就是 Rijndael 算法。
(1)AES 有 5 种加密模式,分别是:
(2)AES 是对称分组加密算法,每组长度为 128bits,即 16 字节。
(3)AES 秘钥的长度只能是16、24 或 32 字节,分别对应三种加密模式 AES-128、AES-192 和 AES-256,三者的区别是加密轮数不同。
AES | 分组长度(字节) | 密钥长度(字节) | 加密轮数 |
---|---|---|---|
AES-128 | 16 | 16 | 10 |
AES-192 | 16 | 24 | 12 |
AES-256 | 16 | 32 | 14 |
下面以 CBC 模式为例,实现 AES 加解密。
package main
import (
"fmt"
"crypto/cipher"
"crypto/aes"
"bytes"
"encoding/base64"
)
// PKCS7Padding fills plaintext as an integral multiple of the block length
func PKCS7Padding(p []byte, blockSize int) []byte {
pad := blockSize - len(p)%blockSize
padtext := bytes.Repeat([]byte{byte(pad)}, pad)
return append(p, padtext...)
}
// PKCS7UnPadding removes padding data from the tail of plaintext
func PKCS7UnPadding(p []byte) []byte {
length := len(p)
paddLen := int(p[length-1])
return p[:(length - paddLen)]
}
// AESCBCEncrypt encrypts data with AES algorithm in CBC mode
// Note that key length must be 16, 24 or 32 bytes to select AES-128, AES-192, or AES-256
// Note that AES block size is 16 bytes
func AESCBCEncrypt(p, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
p = PKCS7Padding(p, block.BlockSize())
ciphertext := make([]byte, len(p))
blockMode := cipher.NewCBCEncrypter(block, key[:block.BlockSize()])
blockMode.CryptBlocks(ciphertext, p)
return ciphertext, nil
}
// AESCBCDecrypt decrypts cipher text with AES algorithm in CBC mode
// Note that key length must be 16, 24 or 32 bytes to select AES-128, AES-192, or AES-256
// Note that AES block size is 16 bytes
func AESCBCDecrypt(c, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
plaintext := make([]byte, len(c))
blockMode := cipher.NewCBCDecrypter(block, key[:block.BlockSize()])
blockMode.CryptBlocks(plaintext, c)
return PKCS7UnPadding(plaintext)
}
// Base64AESCBCEncrypt encrypts data with AES algorithm in CBC mode and encoded by base64
func Base64AESCBCEncrypt(p, key []byte) (string, error) {
c, err := AESCBCEncrypt(p, key)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(c), nil
}
// Base64AESCBCDecrypt decrypts cipher text encoded by base64 with AES algorithm in CBC mode
func Base64AESCBCDecrypt(c string, key []byte) ([]byte, error) {
oriCipher, err := base64.StdEncoding.DecodeString(c)
if err != nil {
return nil, err
}
p, err := AESCBCDecrypt(oriCipher, key)
if err != nil {
return nil, err
}
return p, nil
}
使用示例如下:
func main() {
p := []byte("plaintext")
key := []byte("12345678abcdefgh")
ciphertext, _ := Base64AESCBCEncrypt(p, key)
fmt.Println(ciphertext)
plaintext, _ := Base64AESCBCDecrypt(ciphertext, key)
fmt.Println(string(plaintext))
}
运行输出:
A67NhD3RBiNaMgG6HTm8LQ==
plaintext
以上代码已放到开源 Go 工具库 go-huge-util,大家如果需要,可直接通过 go mod 方式进行 import 然后使用。
import (
huge "github.com/dablelv/go-huge-util"
)
p := []byte("plaintext")
key := []byte("12345678abcdefgh")
ciphertext, _ := huge.Base64AESCBCEncrypt(p, key) // A67NhD3RBiNaMgG6HTm8LQ==
plaintext, _ := huge.Base64AESCBCDecrypt(ciphertext, key) // plaintext
如果想了解 AES 实现原理。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有