本文已参加「新人创作礼」活动,一起开启掘金创作之路。
因为工作需要,需要再次了解AES对称加密的使用
在此,我想说一句,在写一些接口尤其是对接接口的时候,有一些算法,不要用一些封装好的第三方包,这样会给对接非常大的阻碍,就使用最基本的原始包,去实现这个逻辑,这样的话,即使是对接,阻碍也会非常小 举例:Aes 加密方式,如果你直接使用第三方封装好的包,直接进行AES加密,跟就不知道她是使用什么格式,等别的用户来对接时,如果用户使用的语言和你一样,那OK,直接复制粘贴,但是如果语言不一样怎么办?是不是?所以,广大的程序员朋友啊,自己不对外的接口,想怎么玩怎么玩,如果是需要对接外部了,一定要记得,使用最原始的包进行算法的实现,要不然真的很难受
好了,不喷了,我们直接来看我们今天的主题,go AES的 三种加密方式
方式一: CBC
func Test_B_1(t *testing.T) {
origData := []byte("460154561234") // 待加密的数据
key := []byte("9876787656785679") // 加密的密钥
log.Println("原文:", string(origData))
log.Println("------------------ CBC模式 --------------------")
encrypted := AesEncryptCBC(origData, key)
log.Println("密文(hex):", hex.EncodeToString(encrypted))
log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))
decrypted := AesDecryptCBC(encrypted, key)
log.Println("解密结果:", string(decrypted))
}
func AesEncryptCBC(origData []byte, key []byte) (encrypted []byte) {
// 分组秘钥
// NewCipher该函数限制了输入k的长度必须为16, 24或者32
block, _ := aes.NewCipher(key)
blockSize := block.BlockSize() // 获取秘钥块的长度
origData = pkcs5Padding(origData, blockSize) // 补全码
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // 加密模式
encrypted = make([]byte, len(origData)) // 创建数组
blockMode.CryptBlocks(encrypted, origData) // 加密
return encrypted
}
func AesDecryptCBC(encrypted []byte, key []byte) (decrypted []byte) {
block, _ := aes.NewCipher(key) // 分组秘钥
blockSize := block.BlockSize() // 获取秘钥块的长度
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) // 加密模式
decrypted = make([]byte, len(encrypted)) // 创建数组
blockMode.CryptBlocks(decrypted, encrypted) // 解密
decrypted = pkcs5UnPadding(decrypted) // 去除补全码
return decrypted
}
func pkcs5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func pkcs5UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
方式二:ECB
func Test_B_2(t *testing.T) {
origData := []byte("460154561234") // 待加密的数据
key := []byte("9876787656785679") // 加密的密钥
log.Println("原文:", string(origData))
log.Println("------------------ ECB模式 --------------------")
encrypted := AesEncryptECB(origData, key)
log.Println("密文(hex):", hex.EncodeToString(encrypted))
log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))
decrypted := AesDecryptECB(encrypted, key)
log.Println("解密结果:", string(decrypted))
}
func AesEncryptECB(origData []byte, key []byte) (encrypted []byte) {
cipher, _ := aes.NewCipher(generateKey(key))
length := (len(origData) + aes.BlockSize) / aes.BlockSize
plain := make([]byte, length*aes.BlockSize)
copy(plain, origData)
pad := byte(len(plain) - len(origData))
for i := len(origData); i < len(plain); i++ {
plain[i] = pad
}
encrypted = make([]byte, len(plain))
// 分组分块加密
for bs, be := 0, cipher.BlockSize(); bs <= len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
}
return encrypted
}
func AesDecryptECB(encrypted []byte, key []byte) (decrypted []byte) {
cipher, _ := aes.NewCipher(generateKey(key))
decrypted = make([]byte, len(encrypted))
//
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
}
trim := 0
if len(decrypted) > 0 {
trim = len(decrypted) - int(decrypted[len(decrypted)-1])
}
return decrypted[:trim]
}
func generateKey(key []byte) (genKey []byte) {
genKey = make([]byte, 16)
copy(genKey, key)
for i := 16; i < len(key); {
for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
genKey[j] ^= key[i]
}
}
return genKey
}
方式三 : CFB
func Test_B_3(t *testing.T) {
origData := []byte("460154561234") // 待加密的数据
key := []byte("9876787656785679") // 加密的密钥
log.Println("原文:", string(origData))
log.Println("------------------ CFB模式 --------------------")
encrypted := AesEncryptCFB(origData, key)
log.Println("密文(hex):", hex.EncodeToString(encrypted))
log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))
decrypted := AesDecryptCFB(encrypted, key)
log.Println("解密结果:", string(decrypted))
}
func AesEncryptCFB(origData []byte, key []byte) (encrypted []byte) {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
encrypted = make([]byte, aes.BlockSize+len(origData))
iv := encrypted[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(encrypted[aes.BlockSize:], origData)
return encrypted
}
func AesDecryptCFB(encrypted []byte, key []byte) (decrypted []byte) {
block, _ := aes.NewCipher(key)
if len(encrypted) < aes.BlockSize {
panic("ciphertext too short")
}
iv := encrypted[:aes.BlockSize]
encrypted = encrypted[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(encrypted, encrypted)
return encrypted
}