AES(Advanced Encryption Standard)
是一种常用的对称加密算法
三个关键配置
在使用 AES 加密时,IV(初始向量)、Mode(加密模式)和 Padding(填充方式)是三个关键配置,它们直接影响加密的安全性和实用性。
1. 向量 IV(Initialization Vector)
作用:IV 是一个随机或伪随机的数值,用于确保相同的明文在相同密钥加密下生成不同的密文,防止攻击者通过分析密文规律规律。
特点:
- 长度固定,与 AES 块大小一致(AES 块大小为 128 位,即 16 字节)。
- 不需要保密,但必须在加密和解密时使用相同的 IV。
- 每次加密应使用不同的 IV(尤其是在相同密钥下),否则会降低安全性。
- 使用场景:主要用于分组加密模式(如 CBC、CTR 等),ECB 模式不需要 IV(但 ECB 安全性差,不推荐使用)。
2. 模式 Mode(加密模式)
AES 是块加密算法,只能加密固定大小的块(128 位),而实际数据长度通常不固定。加密模式定义了如何将多个数据块串联加密,常见模式包括:
- ECB(Electronic Codebook,电子密码本):
最基础的模式,每个数据块独立加密。
缺点:相同明文块会生成相同密文块,安全性差,容易被破解,不推荐使用。 - CBC(Cipher Block Chaining,密码块链):
每个明文块加密前会与前一个密文块进行 XOR 运算,第一个块则与 IV 进行 XOR。
优点:解决了 ECB 的安全性问题,应用广泛(如 SSL/TLS 早期版本)。
缺点:加密过程是串行的,无法并行处理,效率较低。 - CTR(Counter,计数器模式):
通过生成一个计数器序列,与计数器加密后的结果和明文进行 XOR 得到密文。
优点:加密和解密可以并行处理,效率高,适合流式数据加密。
注意:需要确保计数器不重复,否则会泄露明文。 - GCM(Galois/Counter Mode):
基于 CTR 模式,增加了认证功能(可以检测数据是否被篡改)。
优点:同时提供加密和认证,安全性高,性能好,被 TLS 1.2 + 广泛采用。
其他模式:如 OFB、CFB 等,应用较少,安全性或效率不如上述模式。
3. 填充 Padding
由于 AES 只能加密固定大小的块(128 位),当明文长度不是块大小的整数倍时,需要通过填充方式补足最后一个块,常见填充方式:
- PKCS#7:
最常用的填充方式,填充的字节数等于需要填充的长度。
例如:若最后一个块需要填充 3 字节,则填充0x03 0x03 0x03;若刚好是完整块,也会填充一个完整的块(16 字节0x10)。 - ISO/IEC 7816-4:
第一个填充字节为0x80,后续填充0x00,直到填满块。 - NoPadding:
不填充,要求明文长度必须是块大小的整数倍,否则会报错。适用于已知明文长度的场景(如与 CTR 模式结合使用时,CTR 可处理任意长度)。
总结
- IV:防止相同明文加密后产生相同密文,需随机且与块大小一致。
- Mode:定义多块数据的加密方式,推荐使用 CBC(兼容性好)或 GCM(带认证,更安全)。
- Padding:解决明文长度不是块大小整数倍的问题,推荐使用 PKCS#7。
这些配置需在加密和解密时严格一致,否则会导致解密失败或数据损坏。
建议
建议为每个明文(或每次加密操作)使用不同的 IV,这是保障 AES 加密安全性的重要实践。关于 IV 的存储,可以存入数据库,具体原因和处理方式如下:
-
为什么需要每个明文使用不同的 IV?
AES 的安全性依赖于 “相同明文 + 相同密钥 + 不同 IV” 产生不同密文。如果相同密钥下多次使用相同 IV,攻击者可能通过分析密文规律推断明文(尤其是 CBC 等模式)。
例如:若两次加密相同明文且使用相同 IV,CBC 模式下第一个密文块会完全相同,直接暴露明文关联性。 -
IV 需要保密吗?需要存到数据库里吗?
IV 不需要保密:它的作用是 “随机性” 而非 “机密性”,即使被攻击者获取,也无法单独破解密文(仍需密钥)。
IV 必须存储:解密时需要与加密时完全相同的 IV,否则无法正确解密。因此,IV 需要和密文一起保存(通常与密文拼接或单独存入数据库)。 -
实际存储方式(以数据库为例)
通常有两种处理方式:
方式 1:IV 与密文拼接后存储
加密后将 IV(固定 16 字节)拼在密文前,解密时先截取前 16 字节作为 IV,剩余部分作为密文。
例:存储内容 = IV + 密文(代码中可通过字节拼接实现)。
方式 2:IV 与密文分开存储
在数据库中增加一个iv字段,与ciphertext字段并列存储。解密时同时读取两者即可。 -
注意事项
IV 长度固定:AES 的 IV 长度必须与块大小一致(128 位 = 16 字节),与密钥长度(128/192/256 位)无关。
生成方式:IV 需通过密码学安全的随机数生成器(如 Python 的os.urandom(16))生成,避免使用可预测的值(如时间戳)。
兼容性:确保加密和解密时 IV 的读取方式一致(拼接 / 分字段),否则会解密失败。
示例(伪代码逻辑)
# 加密时
key = 加密密钥(16/24/32字节)
iv = 随机生成16字节(如os.urandom(16))
密文 = aes_encrypt(明文, key, iv)
存储到数据库:(iv, 密文) 或 (iv+密文)# 解密时
从数据库读取iv和密文
明文 = aes_decrypt(密文, key, iv)
总之,IV 需要随密文一起存储(可存数据库),且每次加密生成新的 IV,这是兼顾安全性和可用性的标准做法。