本文对 AES 算法比较常见的几个问题点进行梳理说明。
一、块分组长度
AES 作为块密码算法,加解密的时候,需要将操作数据按固定长度的数据块进行分组后再进行处理。对于AES算法,其分组长度都是固定16字节大小。
AES | 密钥长度(字节) | 分组长度(字节) | 加密轮数 |
---|---|---|---|
AES-128 | 16 | 16 | 10 |
AES-192 | 24 | 16 | 12 |
AES-256 | 32 | 16 | 14 |
二、初始向量
AES 有不同的分组模式,像 ECB 属于最简单的模式,每个分组独立加解密处理,但这种模式是存在安全问题的,不建议使用。而 AES-CBC 分组模式则是比较常用的。
CBC 加密首先是将明文分成固定长度的块,然后将前面一个加密块加密后的密文和下一个明文块进行异或操作,将计算后的结果再用密钥进行加密得到第二个密文块,于此类推与剩余的明文块加密。那第一个明文块加密的时候,因为前面没有被加密的密文,固需要一个初始化向量替代使用。也因此初始化向量长度等于块分组长度。
在使用对称密钥加密时,初始化向量尽量不要重复,否则同样的明文和密钥计算的的密文就是一样的;也因此通常需要把初始化向量和加密数据一起发送给对方。
三、填充方式
对于 CBC 分组模式,如果最后一个分组块长度不足该算法分组固定长度,则需要进行字节填充。针对填充机制,有多种标准,如下是 openssl 库头文件 evp.h 中的声明
/* Padding modes */
#define EVP_PADDING_PKCS7 1
#define EVP_PADDING_ISO7816_4 2
#define EVP_PADDING_ANSI923 3
#define EVP_PADDING_ISO10126 4
#define EVP_PADDING_ZERO 5
默认使用 PKCS7 填充方式,其填充方式就是差多少个字节,就用差的值作为填充值,比如差3个字节,则末尾用3个 03 03 03
字节补充。
四、加密密文长度
填充情况下:
AES 密文长度 = (原文长度/16*16) + 16
或者
AES 密文长度 = (原文长度 + 16) &~ (16-1)