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)]
}