AES 基础
AES 是分组密码,块大小固定 16 字节(128 bit)。加密时需要选择工作模式来处理超过一块的数据。
核心组件(从零实现时需要编写的):
- S-Box:替换表,保证可逆的同时使密文信息熵尽可能大(雪崩效应)
- 密钥扩展(Key Expansion):从原始密钥派生出每一轮需要的轮密钥
- SubBytes:通过 S-Box 做字节替换
- ShiftRows:行移位
- MixColumns:列混合(在 GF(2^8) 上做矩阵乘法)
- AddRoundKey:轮密钥异或
常见工作模式对比
| ECB | CBC | CTR | GCM | |
|---|---|---|---|---|
| 加密 | 每块独立加密 | 前一块密文参与下一块 | 计数器加密后异或明文 | CTR 加密 + GHASH 认证 |
| 填充 | 需要填充 | 需要填充 | 不需要 | 不需要 |
| 并行 | 加密可并行 | 加密不可并行 | 加密解密都可并行 | 加密解密都可并行 |
| 认证 | 不提供 | 不提供 | 不提供 | 内置(AEAD) |
| 安全性 | 最差(相同明文块→相同密文块) | 较好 | 好 | 最好(推荐) |
CTR 模式
CTR 把 AES 从分组密码变成流密码使用:
明文分块:P1, P2, P3 ...
计数器: 1, 2, 3 ...(每次 +1,inc32:只增最右 32 位)
加密每块:C_i = P_i XOR AES(Key, Counter_i)
解密每块:P_i = C_i XOR AES(Key, Counter_i)
加密和解密用的是同一个操作(都是 XOR AES 输出),所以加密能并行,解密也能并行。
GCM 模式(Galois/Counter Mode)
GCM = CTR 加密 + GHASH 认证,属于 AEAD(认证加密)模式,一个模式同时搞定加密和完整性校验。
完整流程
发送方:
步骤 1 — CTR 加密(跟普通 CTR 一样)
J0 = IV || 0^31 || 1 ← 初始计数器(只用于算 Tag)
Counter_1 = J0 + 1 ← 加密第 1 块
Counter_2 = J0 + 2 ← 加密第 2 块
...
C_i = P_i XOR AES(Key, Counter_i)
步骤 2 — GHASH 认证(GCM 独有)
H = AES(Key, 0) ← 哈希子密钥,固定值,不是密钥本身
Y0 = 0
Y1 = (Y0 ⊕ C1) ⊗ H ← ⊗ 是 GF(2^128) 有限域乘法
Y2 = (Y1 ⊕ C2) ⊗ H
Y3 = (Y2 ⊕ C3) ⊗ H
...
最后混入 AAD 和密文长度信息,得到 S
步骤 3 — 生成认证标签
Tag = S ⊕ AES(Key, J0) ← 16 字节
步骤 4 — 发送
发送:密文 C1 C2 C3 ... + Tag
接收方:
1. 用同样的 Key 和 J0 重新算 Tag'
2. 对比 Tag' 和收到的 Tag
3. 一样 → 没被篡改,用 CTR 解密
4. 不一样 → 拒绝,不解密
为什么改一个 bit 就能检测到
正常发送方: 攻击者把 C1 改成 C1':
Y1 = (0 ⊕ C1) ⊗ H Y1' = (0 ⊕ C1') ⊗ H ← 变了
Y2 = (Y1 ⊕ C2) ⊗ H Y2' = (Y1' ⊕ C2) ⊗ H ← 跟着变
S = Y2 S' = Y2' ← 完全不同
Tag = S ⊕ AES(Key, J0) Tag' = S' ⊕ AES(Key, J0) ≠ Tag
Tag' ≠ Tag → 校验失败
核心是 ⊗ H(有限域乘法)具有高度混合特性,输入差一个 bit 输出就面目全非,而且误差会通过累加传播放大到每一步(滚雪球效应)。
GCM vs ChaCha20-Poly1305 对比
两者都是 AEAD 模式(加密 + 认证一体),但认证部分的底层数学完全不同:
| GCM | ChaCha20-Poly1305 | |
|---|---|---|
| 加密 | AES-CTR(分组密码) | ChaCha20(流密码) |
| 认证算法 | GHASH:GF(2^128) 有限域多项式乘法 | Poly1305:mod 2^130-5 整数多项式求值 |
| 认证密钥 | H = AES(Key, 0),固定值 | r, s = ChaCha20(Key, 0),一次性密钥对 |
| 性能倾向 | 硬件友好(AES-NI 指令加速) | 软件友好(纯加减运算,不需要查表) |
GHASH
- 把数据块依次做 GF(2^128) 乘法累加
- 依赖有限域的代数结构
- H 每次会话都一样(同一个 Key)
Poly1305
- 把消息当成多项式,在 r 处求值,然后加 s
- 本质是多项式求值 + 一次性密钥
- r 每次会话不同(从 ChaCha20 派生),天然是一次性 MAC
两者设计目标相同(算一个 16 字节认证标签),但适用场景不同:有 AES-NI 硬件加速选 GCM,没有则选 ChaCha20-Poly1305。
AAD(Additional Authenticated Data)
AAD 在 GCM 和 ChaCha20-Poly1305 里作用相同:不加密但需要认证的附加数据。
典型用途:
- HTTP 请求头(明文传输,但需要确保没被篡改)
- 网络包的元数据(IP 地址、端口号、包序号)
- 协议版本号
AAD 被纳入认证标签的计算过程,但不参与加密。如果 AAD 被篡改,Tag 校验同样会失败。