AES 的五种模式该怎么选

工具相关 ·

用 AES 加密数据时,第一个要做的决定不是密钥长度,而是模式。同一个密钥、同一段明文,用不同模式加密会得到完全不同的结果,安全性差别也很大。ECB、CBC、CFB、OFB、CTR 这五种常见模式各有适用场景,选错了可能让加密形同虚设。

分组密码与模式的角色

AES 本身是一个分组密码,它的能力是:给定 16 字节的密钥和一个 16 字节的数据块,输出 16 字节的密文。注意单位——一次只能处理 16 字节。

但实际要加密的数据往往远大于 16 字节。如何把长数据切分成块、如何把多个块的加密结果串联起来、如何保证相同内容不会产生相同密文,这些问题的解决方案就叫「模式」。

所以模式不是 AES 的可选项,而是使用 AES 的必需组成部分。没有模式,AES 只能加密恰好 16 字节的数据。

五种模式的核心差异

五种模式的差别可以归结为两个问题:每个块是否独立加密*,以及*块与块之间是否有关联。

ECB 是最简单的:每个块独立加密,块之间没有任何关联。相同的明文块必然产生相同的密文块。它不推荐使用,后面会专门讨论原因。

CBC 引入了前一块的密文作为输入:当前明文先与前一块密文异或,再送去加密。这样即使两个块内容相同,因为前一块的密文不同,最终的密文也不同。CBC 需要一个初始向量(IV)来启动第一个块,是最常见的默认选择。

CFB、OFB、CTR 这三种属于流式模式。它们把分组密码当作密钥流生成器使用:先用 AES 生成一段密钥流,再与明文异或得到密文。这个设计带来两个好处——密文长度与明文完全相同,不需要填充;解密时不需要做逆运算,加密和解密用的是同一段代码。

三者之间的区别在于密钥流的生成方式。CFB 用前一段密文参与生成下一段密钥流,因此加密必须串行,但解密可以并行。OFB 用前一段密钥流生成下一段,加解密都不能并行。CTR 把计数器加密得到密钥流,每个块的密钥流可以独立计算,因此加解密都能并行,是目前最常用也最高效的流式模式。

模式是否需要 IV是否需要填充可并行推荐度
ECB否是是不推荐
CBC是是仅解密兼容性首选
CFB是否仅解密特定场景
OFB是否否特定场景
CTR是否是流式场景推荐

怎么按场景选

如果是要与已有系统对接,选择往往不由自己决定——对端用什么,你就得用什么。这种情况下 CBC 的兼容性最好,几乎所有语言和库都支持。

如果是新设计的系统,建议直接使用带认证的模式,例如 GCM 或 CCM。这类模式在加密的同时生成一个认证标签,能够检测出密文是否被篡改。传统的五种模式只保证机密性,不保证完整性——攻击者虽然读不懂内容,但可以修改密文,导致解密结果被静默篡改。

如果需要流式处理(例如加密网络流、处理长度不确定的数据),CTR 是最合适的选择。它不需要填充,密文长度与明文一致,而且可以并行加速。

CFB 和 OFB 在现代实践中使用较少,多数情况下可以用 CTR 替代。它们更多出现在一些历史协议里。

加解密双方必须完全一致

无论选择哪种模式,有一件事必须做到:双方约定的参数要完全一致。

这个「完全一致」包括:算法(AES)、密钥、模式、填充方式、IV 的传递方式、密文的编码(Hex 还是 Base64)。其中任何一项不同,解密都会失败或者得到乱码。

实际调试中最常见的失败原因,就是某一方用了不同的填充方式,或者把 IV 的传递方式搞错了。建议把这些约定写进接口文档,并在对接时用一段固定的测试向量验证一遍。

检查清单

  • AES 一次只能处理 16 字节,加密长数据必须借助模式
  • ECB 每块独立加密,会泄露重复结构,不推荐使用
  • CBC 用前一块密文参与运算,需要随机 IV,兼容性最好
  • CFB、OFB、CTR 是流式模式,无需填充,密文长度与明文一致
  • CTR 可并行且高效,流式场景优先选择
  • 新系统优先考虑 GCM 等带认证的模式,它同时保证机密性与完整性
  • 双方必须完全一致地约定算法、密钥、模式、填充、IV 传递方式与密文编码
阅读 12