以下内容转载自 https://cloud.tencent.com/developer/article/1420428
版权声明:感谢您对博文的关注!
https://blog.csdn.net/K346K346/article/details/89387460
利用Go提供的AES加解密与Base64编解码包,我们可以轻松地实现AES的加解密。实现之前,首先了解一下AES的一些常识点。 (1)AES有5种加密模式,分别是: (a)电码本模式(Electronic Codebook Book,ECB); (b)密码分组链接模式(Cipher Block Chaining ,CBC),如果明文长度不是分组长度16字节的整数倍需要进行填充; (c)计算器模式(Counter,CTR); (d)密码反馈模式(Cipher FeedBack,CFB); (e)输出反馈模式(Output FeedBack,OFB)。
(2)AES是对称分组加密算法,每组长度为128bits,即16字节。
(3)AES秘钥的长度只能是16、24或32字节,分别对应三种AES,即AES-128, AES-192和AES-256,三者的区别是加密的轮数不同;
下面以CBC模式为例,实现AES加解密。
package aeswrap
import (
"fmt"
"crypto/cipher"
"crypto/aes"
"bytes"
"encoding/base64"
)
//@brief:填充明文
func PKCS5Padding(plaintext []byte, blockSize int) []byte{
padding := blockSize-len(plaintext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)},padding)
return append(plaintext,padtext...)
}
//@brief:去除填充数据
func PKCS5UnPadding(origData []byte) []byte{
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
//@brief:AES加密
func AesEncrypt(origData, key []byte) ([]byte, error){
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
//AES分组长度为128位,所以blockSize=16,单位字节
blockSize := block.BlockSize()
origData = PKCS5Padding(origData,blockSize)
blockMode := cipher.NewCBCEncrypter(block,key[:blockSize]) //初始向量的长度必须等于块block的长度16字节
crypted := make([]byte, len(origData))
blockMode.CryptBlocks(crypted,origData)
return crypted, nil
}
//@brief:AES解密
func AesDecrypt(crypted, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
//AES分组长度为128位,所以blockSize=16,单位字节
blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) //初始向量的长度必须等于块block的长度16字节
origData := make([]byte, len(crypted))
blockMode.CryptBlocks(origData, crypted)
origData = PKCS5UnPadding(origData)
return origData, nil
}
func main(){
//key的长度必须是16、24或者32字节,分别用于选择AES-128, AES-192, or AES-256
var aeskey = []byte("12345678abcdefgh")
pass := []byte("vdncloud123456")
xpass, err := AesEncrypt(pass,aeskey)
if err != nil {
fmt.Println(err)
return
}
pass64 := base64.StdEncoding.EncodeToString(xpass)
fmt.Printf("加密后:%v\n",pass64)
bytesPass, err := base64.StdEncoding.DecodeString(pass64)
if err != nil {
fmt.Println(err)
return
}
tpass, err := AesDecrypt(bytesPass, aeskey)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("解密后:%s\n", tpass)
}
编译运行输出:
加密后:Z9Mz4s6LDwYpIam4z+fqxw==
解密后:vdncloud123456
如果想了解AES实现原理,可参考AES加密算法的详细介绍与实现。