首页/安全/加密与证书速查/填充预言(padding oracle)与防护
加密算法基础95 条

填充预言(padding oracle)与防护

服务端把填充错误与认证失败区分开时,攻击者可据此逐字节推断明文;防护要点是改用 AEAD、统一错误响应并保持处理耗时稳定。

加密与证书速查安全更新于 2026-10-13

填充预言是什么

填充预言(padding oracle)指的是一种可被外部观测的判定差异:服务端解密失败时,把「填充错误」和「消息认证失败」区分开来反馈(错误码、页面内容、响应耗时不同),攻击者据此每次确定一个字节,最终逐字节还原明文。它不是算法漏洞,而是使用方式泄漏信息,典型出现在 CBC 加解密的接口与早期 TLS 实现上。

基本信息

成因解密错误被分类暴露:错误码、页面、耗时差异
典型场景CBC + MAC 的 TLS 1.2 及更早、自研 Cookie/Token 加密
受影响算法CBC 类分组模式(含 AES-CBC、3DES-CBC)
不受影响AEAD(GCM、ChaCha20-Poly1305、CCM)
根治手段改用 AEAD 并统一错误响应与处理耗时
缓解手段Encrypt-then-MAC(RFC 7366)并保持常量时间处理

典型使用场景

  • TLS 服务端梳理:把 CBC 套件从配置中移除,全面转向 AEAD
  • 自研加密接口整改:登录态、优惠券、下载令牌等被加密后交给客户端的字段
  • 代码审计:查找「先解密再校验格式」的写法,这类结构天然存在错误分类
  • 渗透测试复盘:把已披露的填充预言类漏洞映射到自身代码的同类模式
  • 遗留系统加固:无法立即换算法时,先消除错误分类与耗时差异

服务端只保留 AEAD 套件

服务端只保留 AEAD 套件
# TLS 1.2 侧只留 ECDHE 与 AEAD 组合,CBC 全部去掉
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers on;
# 验证:确认协商结果里没有 CBC
openssl s_client -connect example.com:443 -tls1_2 </dev/null 2>/dev/null | grep 'Cipher'

应用层防护要点

应用层防护要点
# 反面写法:解密失败与校验失败返回不同状态码,攻击者可区分
if not padding_ok(data): return 400   # 泄漏点:填充错误
if not mac_ok(data):     return 401   # 泄漏点:认证失败

# 正面写法:统一出口,且不把异常细节写进响应
ok, plain = try_decrypt_and_verify(data)
if not ok:
    log_internal_reason()             # 细节只进内部日志
    return same_error_response()       # 对外只有一种错误
# 另外:比较 MAC 用常量时间函数,避免耗时差异成为新的判定通道

旁路与对策对照

旁路形式攻击者能观测到什么对策
错误码不一致填充错误返回 400、认证失败返回 401对外统一为一种错误码
页面内容差异不同错误返回不同页面或字段统一响应体,去掉差异化文案
响应耗时差异填充校验与 MAC 校验的处理时间不同改用常量时间比较,必要时统一拒绝路径
连接行为差异提前关闭连接或发送不同告警保持一致的连接处理与告警策略
日志与监控差异外部可触发不同告警类别只在内部记录细节,不外泄分类信息
只改错误文案往往不够:加解密顺序、MAC 覆盖范围与比较方式都会留下可观测差异。真正的根治是改用 AEAD,让「解密失败」只有一种可能;在无法换算法的存量系统里,至少要同时消除错误分类、耗时差异与连接行为差异。
Encrypt-then-MAC(先加密再对密文做 MAC)比 MAC-then-Encrypt 更安全:接收方可以先验 MAC 再解密,MAC 不通过就统一拒绝,从根本上避免进入「解密后才发现填充错误」的路径。TLS 的 Encrypt-then-MAC 扩展即为此提供(RFC 7366)。

易错点

  • 对密文「先解密、再看格式」的老代码只做局部补丁:错误分类虽然改了,处理顺序与耗时差异仍在,攻击面只是变隐蔽
  • 把异常堆栈或内部错误码透出到接口响应:等价于把判定结果直接告诉攻击者
  • MAC 不覆盖 IV 或长度字段:攻击者可篡改这些字段而不影响 MAC 校验,进而影响解密结果
  • 认为禁用了 CBC 就万事大吉:自研的 Token、Cookie 加密仍可能使用 CBC 逻辑,需在代码层面统一排查
  • 只做一次整改不做回归:新增接口若复制了老写法,问题会重新出现,应把这套约束写进代码规范与评审清单

数据来源与参考

  • RFC 7366(Encrypt-then-MAC for TLS)
  • NIST SP 800-38A
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌