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加密过程

  1. 明文划分为等长分组
  2. 最后一个分组按规则填充
  3. 每个分组明文与前一个密文分组异或
    • 第一个分组与IV(初始化向量)异或
  4. 异或结果用密钥加密

特点:

  • IV影响后续所有加密块
  • 安全实践中IV应随机生成

2.2 CBC解密过程

  1. 使用密钥解密当前密文块
  2. 解密结果与前一个密文块异或
    • 第一个块与IV异或
  3. 最后移除填充

3. Padding Oracle原理

3.1 基本概念

  • Padding Oracle:能提供填充合法性反馈的服务或实体

    • 输入任意密文,返回填充是否合法的判断
    • 错误填充报错,正确填充不报错
  • Oracle术语含义:预言机,能直接获取特定问题答案的抽象计算模型

3.2 攻击原理

利用服务对填充验证的反馈,无需密钥即可逐字节破解密文:

  1. 攻击者可以控制IV和密文
  2. 服务解密后会验证填充合法性
  3. 通过精心构造IV,利用服务的错误信息推断中间值
  4. 最终计算出明文

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!

密文分组:

  1. IV: e14950e98b0904dd282de280609b7314
  2. 密文块1: fcc1b431b32bc2d5f0f290dd64df1a3f
  3. 密文块2: 66cce304e5ea77bec3237bd42546f029

5. 攻击步骤详解

5.1 攻击准备

  1. 获取密文C和IV
  2. 将密文分成块:C₁, C₂, ..., Cₙ
  3. 目标:解密最后一个块Cₙ

5.2 单字节破解

  1. 构造修改的IV',其中:
    • 前15字节随机
    • 最后1字节遍历0x00-0xFF
  2. 提交(IV', Cₙ)到服务
  3. 观察响应:
    • 填充错误:继续尝试
    • 无错误:找到有效字节

5.3 计算中间值

当找到使填充有效的IV'[15]时:

Intermediate[15] = IV'[15] ⊕ PaddingValue

5.4 计算明文

Plaintext[15] = Intermediate[15] ⊕ OriginalIV[15]

5.5 扩展攻击

  1. 破解一个字节后,修改PaddingValue为0x02
  2. 重复过程破解前一个字节
  3. 依次破解整个块

6. 防御措施

  1. 使用认证加密:如AES-GCM
  2. 统一错误响应:填充错误与其他错误无区别
  3. 使用加密MAC:先验证MAC再解密
  4. 限制解密尝试:频率限制或CAPTCHA

7. 总结

Padding Oracle攻击利用的是:

  1. CBC模式的可控IV特性
  2. 服务对填充验证的差异性响应
  3. 通过暴力破解逐步推断中间值

理解此攻击有助于设计更安全的加密系统实现。

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) 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 ]时: 5.4 计算明文 5.5 扩展攻击 破解一个字节后,修改PaddingValue为0x02 重复过程破解前一个字节 依次破解整个块 6. 防御措施 使用认证加密 :如AES-GCM 统一错误响应 :填充错误与其他错误无区别 使用加密MAC :先验证MAC再解密 限制解密尝试 :频率限制或CAPTCHA 7. 总结 Padding Oracle攻击利用的是: CBC模式的可控IV特性 服务对填充验证的差异性响应 通过暴力破解逐步推断中间值 理解此攻击有助于设计更安全的加密系统实现。