< BACK_TO_INDEX

AES 模式与 GCM 认证加密

PUBLISHED:

AES 模式与 GCM 认证加密

AES 基础

AES 是分组密码,块大小固定 16 字节(128 bit)。加密时需要选择工作模式来处理超过一块的数据。

核心组件(从零实现时需要编写的):

  • S-Box:替换表,保证可逆的同时使密文信息熵尽可能大(雪崩效应)
  • 密钥扩展(Key Expansion):从原始密钥派生出每一轮需要的轮密钥
  • SubBytes:通过 S-Box 做字节替换
  • ShiftRows:行移位
  • MixColumns:列混合(在 GF(2^8) 上做矩阵乘法)
  • AddRoundKey:轮密钥异或

常见工作模式对比

ECBCBCCTRGCM
加密每块独立加密前一块密文参与下一块计数器加密后异或明文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 模式(加密 + 认证一体),但认证部分的底层数学完全不同:

GCMChaCha20-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 校验同样会失败。