Padding Oracle原理深入剖析与实践
字数 1653 2025-08-18 11:36:57
Padding Oracle攻击原理与实践详解
1. 核心背景知识
1.1 分组加密算法
分组加密算法(Block Cipher)将明文划分为等长的数据块进行加密处理,主要算法包括:
- DES/3DES:分组长度64bit(8bytes)
- AES:分组长度128bit(16bytes)
- AES-128、AES-192、AES-256的区别仅在于密钥长度,分组长度相同
1.2 Padding(填充)
分组加密要求输入长度为分组大小的整数倍,填充规则:
- 缺N个字节就填充N个0xN
- 示例:缺5字节填充5个0x05
- 明文恰好为分组整数倍时,需填充完整分组
- 示例:8字节明文需填充8个0x08
1.3 PKCS#5与PKCS#7填充
- PKCS#5:仅支持8字节填充
- PKCS#7:支持1-255字节填充,是PKCS#5的超集
- 填充方式相同,PKCS#7兼容PKCS#5
1.4 加密操作模式
常见分组加密模式:
- ECB(电子密码本模式)
- CBC(密码分组链接模式) - Padding Oracle攻击的目标
- CFB(密码反馈模式)
- OFB(输出反馈模式)
- CTR(计数器模式)
2. CBC模式详解
2.1 CBC加密过程
- 明文划分为等长分组
- 最后一个分组按规则填充
- 每个分组明文与前一个密文分组异或
- 第一个分组与IV(初始化向量)异或
- 异或结果用密钥加密
特点:
- IV影响后续所有加密块
- 安全实践中IV应随机生成
2.2 CBC解密过程
- 使用密钥解密当前密文块
- 解密结果与前一个密文块异或
- 第一个块与IV异或
- 最后移除填充
3. Padding Oracle原理
3.1 基本概念
-
Padding Oracle:能提供填充合法性反馈的服务或实体
- 输入任意密文,返回填充是否合法的判断
- 错误填充报错,正确填充不报错
-
Oracle术语含义:预言机,能直接获取特定问题答案的抽象计算模型
3.2 攻击原理
利用服务对填充验证的反馈,无需密钥即可逐字节破解密文:
- 攻击者可以控制IV和密文
- 服务解密后会验证填充合法性
- 通过精心构造IV,利用服务的错误信息推断中间值
- 最终计算出明文
3.3 攻击条件
- 使用CBC模式的分组加密
- 服务对填充验证有不同响应
- 攻击者能获取加密结果并提交任意密文
4. 实践示例
4.1 示例服务代码(Python Flask)
from flask import Flask, request
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
app = Flask(__name__)
KEY = bytes.fromhex("d7c910a97f037785efb23566ae99d3fc")
iv = bytes.fromhex("e14950e98b0904dd282de280609b7314")
@app.route('/encrypt')
def encrypt():
plain_text = request.args.get('pt', '').encode('utf-8')
cipher = AES.new(KEY, AES.MODE_CBC, iv)
cipher_text = cipher.encrypt(pad(plain_text, AES.block_size))
return 'crypted: {}{}'.format(iv.hex(),cipher_text.hex())
@app.route('/decrypt')
def decrypt():
cipher_text = bytes.fromhex(request.args.get('ct', ''))
iv = cipher_text[:16]
cipher = AES.new(KEY, AES.MODE_CBC, iv)
plain_text = unpad(cipher.decrypt(cipher_text[16:]), AES.block_size)
return 'decrypted: {}'.format(plain_text)
if __name__ == '__main__':
app.run(debug=True, port=8083)
4.2 服务功能
-
/encrypt:加密接口- 参数:
pt(明文) - 返回:IV+密文的十六进制串
- 参数:
-
/decrypt:解密接口- 参数:
ct(密文) - 返回:解密后的明文
- 参数:
4.3 示例加密结果
明文:w4ter0 is awesome!
密文分组:
- IV:
e14950e98b0904dd282de280609b7314 - 密文块1:
fcc1b431b32bc2d5f0f290dd64df1a3f - 密文块2:
66cce304e5ea77bec3237bd42546f029
5. 攻击步骤详解
5.1 攻击准备
- 获取密文C和IV
- 将密文分成块:C₁, C₂, ..., Cₙ
- 目标:解密最后一个块Cₙ
5.2 单字节破解
- 构造修改的IV',其中:
- 前15字节随机
- 最后1字节遍历0x00-0xFF
- 提交(IV', Cₙ)到服务
- 观察响应:
- 填充错误:继续尝试
- 无错误:找到有效字节
5.3 计算中间值
当找到使填充有效的IV'[15]时:
Intermediate[15] = IV'[15] ⊕ PaddingValue
5.4 计算明文
Plaintext[15] = Intermediate[15] ⊕ OriginalIV[15]
5.5 扩展攻击
- 破解一个字节后,修改PaddingValue为0x02
- 重复过程破解前一个字节
- 依次破解整个块
6. 防御措施
- 使用认证加密:如AES-GCM
- 统一错误响应:填充错误与其他错误无区别
- 使用加密MAC:先验证MAC再解密
- 限制解密尝试:频率限制或CAPTCHA
7. 总结
Padding Oracle攻击利用的是:
- CBC模式的可控IV特性
- 服务对填充验证的差异性响应
- 通过暴力破解逐步推断中间值
理解此攻击有助于设计更安全的加密系统实现。