Go AES加密(CBC模式)

TrumanWong
2/24/2023
TrumanWong

前言

高级加密标准A dvanced Encryption Standard,缩写AES,又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。现在,高级加密标准已然成为对称密钥加密中最流行的算法之一。

该算法为比利时密码学家Joan DaemenVincent Rijmen所设计,结合两位作者的名字,以Rijndael为名投稿高级加密标准的甄选流程。

对称加密

AES是对称加密算法,优缺点如下:

AES加密需要:明文+密钥+偏移量IV+密码模式(算法/模式/填充)

AES解密需要:密文+密钥+偏移量IV+密码模式(算法/模式/填充)

AES算法模式一般为AESCBCPKCS7Padding等。

加密模式

AES的加密模式有以下几种

填充模式

编码

package encrypt

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
)

// AesCBCEncrypt key密钥长度必须为16/24/32位, iv偏移量
func AesCBCEncrypt(input, key, iv []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	input = PKCS7Padding(input, block.BlockSize())
	// 偏移量,不传取密钥的前16个字符
	if len(iv) == 0 {
		iv = key[:block.BlockSize()]
	}
	// 加密模式
	blockMode := cipher.NewCBCEncrypter(block, iv)
	encrypt := make([]byte, len(input))
	blockMode.CryptBlocks(encrypt, input)
	return encrypt, nil
}

// AesCBCDecrypt key密钥长度必须为16/24/32位
func AesCBCDecrypt(input, key, iv []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	// 偏移量,不传取密钥的前16个字符
	if len(iv) == 0 {
		iv = key[:block.BlockSize()]
	}
	// 加密模式
	blockMode := cipher.NewCBCDecrypter(block, iv)
	decrypt := make([]byte, len(input))
	blockMode.CryptBlocks(decrypt, input)
	decrypt = PKCS7UnPadding(decrypt)
	return decrypt, nil
}

func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padText...)
}

func PKCS7UnPadding(origData []byte) []byte {
	length := len(origData)
	unPadding := int(origData[length-1])
	return origData[:(length - unPadding)]
}