跳转至

密码学攻击手法

密码学攻击手法


一、分组密码攻击

1.1 ECB 模式攻击

原理:ECB 模式下,相同的明文分组产生相同的密文分组,密文保留了明文的模式特征。

攻击方法:

  1. 块重排攻击:截获密文后,将密文块重新排列组合,解密后得到语义被篡改的明文。
Text Only
原始密文块:C1 | C2 | C3 | C4
重排后密文:C4 | C2 | C3 | C1    → 对应明文块顺序被交换
  1. Byte-at-a-time 解密:在未知明文之前注入可控前缀,利用分块边界逐步爆破未知明文的每个字节。
Text Only
注入 "AAAAAAA"(7个A)→ 未知明文首字节被推到已知块末尾
爆破:发送 "AAAAAAAx" 对比密文块,找出匹配项即为未知字节
逐字节推进即可完全解密
  1. Cut-and-Paste 攻击:从已知密文中剪切一个特定块,拼接到目标密文中,实现伪造(如将特权信息块嫁接到低权限用户密文中)。

实际案例:Adobe 2013 密码泄露使用 ECB 加密密码提示,相同密码提示生成相同密文块而被分析。

1.2 CBC Padding Oracle 攻击(重点)

原理:PKCS#7 填充要求明文末尾必须是合法的填充值(如 \x02\x02 或 \x05\x05\x05\x05\x05)。服务器解密后校验填充是否合法,若返回不同错误信息,攻击者可利用此 Oracle 逐个字节恢复明文。

攻击步骤:

Text Only
假设密文分组:C1 | C2(解密后为 P1 | P2 = D(C1) ⊕ IV | D(C2) ⊕ C1)

目标:恢复中间值 D(C2),进而恢复 P2 = D(C2) ⊕ C1

步骤 1:爆破 D(C2) 最后一个字节
  - 修改 C1 最后一个字节为 0x00 ~ 0xFF,发送 (C1', C2)
  - 当解密后最后一个明文字节为 0x01(合法填充)时,服务器返回正确
  - D(C2)的末字节 = C1'末字节 ⊕ 0x01

步骤 2:爆破倒数第二个字节
  - 先固定末字节使得解密后末字节为 0x02
  - 再爆破倒数第二个字节使得解密后为 0x02(合法填充 \x02\x02)
  - 重复上述过程恢复全部 16 字节

最终:P2 = D(C2) ⊕ C1,明文完全恢复

填充合法性对应关系(16 字节分组):

解密后末尾 合法? 含义
...\x01 ✅ 填充 1 个 0x01
...\x02\x02 ✅ 填充 2 个 0x02
...\x05\x05\x05\x05\x05 ✅ 填充 5 个 0x05
...\x10\x10...\x10(16个) ✅ 整块填充
...\x04\x00\x00\x00 ❌ 末尾必须和填充计数匹配
...\x00 ❌ 0x00 不是合法填充值

Bypass 手段(真实环境变异):

环境 绕过方法
不返回错误详情(统一 500) 利用时序差异(错误填充通常响应更慢)
统一错误码但有 Content-Length 差异 响应体长度不同可区分
HTTP 状态码一致但有特定 header 关注 Set-Cookie、X-Error headers
解密后抛异常导致连接关闭 连接重置 = Oracle
WebSockets 持续探测,逐字节恢复

关键条件: - 攻击者需要能获取到密文 C1 和 C2 - C1 必须是攻击者可修改的(通常在 cookie 或 POST body 中) - 服务器必须返回可区分的填充错误信息(Oracle)

典型漏洞场景:

  • ASP.NET 的 WebResource.axd Padding Oracle(CVE-2010-3332,POET 工具)
  • Java JSF ViewState 反序列化前的 Padding Oracle
  • 自定义加密 Cookie 反序列化失败抛出 CryptoException

防御:

  • Encrypt-then-MAC(先加密再计算 MAC),解密前先验证 MAC
  • 统一错误响应,不泄露填充错误细节
  • 使用 AEAD 模式(AES-GCM),从根本上消除 padding

1.3 CBC 比特翻转攻击(Bit Flipping)

原理:CBC 解密中 P[i] = D(C[i]) ⊕ C[i-1]。修改 C[i-1] 的某一位,P[i] 对应位置将被翻转(0→1, 1→0),这是确定性的,无需任何 Oracle。

应用场景:

Text Only
原始明文:{"admin": 0, "user": "attacker"}
修改 C[i-1] 某一位:将 0 翻转为 1 → {"admin": 1, "user": "attacker"}(非法填充也会出现但反序列化器可能容忍)

关键点: - 比特翻转无需猜测,完全确定 - 下一个明文块会变成乱码(可接受,取决于解析器的容错性) - 不能控制字节的精确值,只能翻转位

防御:使用 AEAD 模式或 Encrypt-then-MAC。

1.4 IV 可预测 / 固定 IV 攻击

CBC 模式下 IV 必须不可预测:

  • BEAST 攻击:TLS 1.0 中 CBC 模式下,IV 是上一个密文块,攻击者可观测并预测,配合 JavaScript 逐步恢复 session cookie
  • 固定 IV:攻击者可以在第一个块上进行 Padding Oracle 攻击,IV 相当于 C1 的前一个块

真实场景: - Web 应用每请求都使用固定 IV,攻击者可逐块解密 cookie - API 接口,IV 从时间戳派生,攻击者收集足够数据后可预测 IV

1.5 Nonce 重用攻击(CTR/GCM 模式)

原理:CTR 和 GCM 模式的安全性建立在 Nonce 唯一性之上。

CTR Nonce 重用:

Text Only
C1 = P1 ⊕ E(Key, Nonce || Counter)
C2 = P2 ⊕ E(Key, Nonce || Counter)  ← 同一 Nonce!

C1 ⊕ C2 = P1 ⊕ E(...) ⊕ P2 ⊕ E(...) = P1 ⊕ P2

已知 P1 或 P2 任一方,另一方可立即恢复

GCM Nonce 重用:更危险。攻击者可以恢复认证子密钥 H,进而伪造任意密文并生成有效的认证标签。

真实案例: - GitHub Action 缓存中使用静态 Nonce(CVE-2024-43404) - 多个数据包用同一 key-nonce 对 - 虚拟机快照/回滚导致 Nonce 重置

防御:Nonce 由 CSPRNG 生成 96 位随机值,或用单调计数器确保从未重用。


二、非对称加密攻击

2.1 Bleichenbacher 攻击(PKCS#1 v1.5 填充)

原理:PKCS#1 v1.5 加密填充格式为 0x00 0x02 [随机非零填充] 0x00 [明文]。服务器收到解密后的数据会检查前两个字节是否为 0x00 0x02。若返回不同错误,攻击者可构造上万次请求逐步缩小明文范围,最终恢复明文。

攻击步骤: 1. 截获密文 C 2. 选择一个值 s,计算 C' = C × s^e mod n,发给服务器 3. 若服务器正确解密(返回 PKCS conforming 响应),则获知 m × s 满足 0x00 0x02 ... 格式 4. 重复上述步骤,每次将 m 的可能区间缩小,最终唯一确定 m

真实案例: - ROBOT Attack(2018):多个 TLS 实现仍受此攻击,Facebook Pay、Cisco ACE 等 - DROWN Attack:使用 SSLv2 的 Bleichenbacher 攻击变种

2.2 小指数攻击(e=3 广播攻击)

原理:RSA 加密 C = M^e mod N。若 e=3,同一明文 M 发给三个不同接收者(N1, N2, N3 两两互质),攻击者可:

Text Only
C1 = M^3 mod N1
C2 = M^3 mod N2
C3 = M^3 mod N3

由中国剩余定理(CRT)解出 M^3,再开立方根得到 M。无需分解 N。

条件:小指数 e + 至少 e 组密文 + 同一明文 + 不同模数。

防御:使用 OAEP 填充使每次加密结果不同;使用 e=65537。

2.3 共模攻击

原理:同一明文 M 用同一模数 N 但不同指数 e1、e2 加密(gcd(e1, e2)=1),攻击者无需分解 N 即可恢复明文。

Text Only
C1 = M^e1 mod N
C2 = M^e2 mod N
gcd(e1, e2) = 1 → 存在 s1, s2 使得 e1×s1 + e2×s2 = 1

M = C1^s1 × C2^s2 mod N

条件:不同用户共享同一个 N、使用不同 e。

防御:每个用户生成独立的 N,绝不共享模数。

2.4 Wiener 攻击

原理:若 RSA 私钥 d 过小(d < N^0.25 × ⅓),可通过连分数展开从公钥(N, e)高效恢复 d。

Text Only
e/N → 连分数展开 → 找到收敛项 k/d → 验证得出 d

条件:d 过小或 p 和 q 太接近。

真实案例: - 智能卡中为了加速计算使用小 d - 嵌入式设备中密钥生成不当

防御:使用大指数 d(至少 N^0.5 数量级),或使用中国剩余定理加速(CRT-RSA)。

2.5 ROCA 攻击(CVE-2017-15361)

原理:Infineon 密码库生成 RSA 密钥时存在严重缺陷,使用快速但不安全的素数生成算法,导致生成的质数具有特殊结构。攻击者可利用 Coppersmith 方法在时间内分解密钥。

影响: - 数十万智能卡、TPM 芯片 - 爱沙尼亚电子身份证(2017年紧急停用) - YubiKey 4、Microsoft 受信平台模块

检测:Nexus-sw/ROCA 在线检测工具可判断密钥是否受影响。

2.6 ECDSA Nonce 重用

原理:ECDSA 签名时若 Nonce k 重用,攻击者可直接恢复私钥。

Text Only
两个签名使用相同 k:
s1 = k⁻¹(z1 + r × d) mod n
s2 = k⁻¹(z2 + r × d) mod n

d = (s1 × z2 - s2 × z1) / (r × (s2 - s1)) mod n

真实案例:Sony PS3 签名密钥泄露(2010)就是因为 ECDSA Nonce 重用。


三、哈希攻击

3.1 长度扩展攻击

原理:Merkle-Damgård 构造的哈希函数(MD5、SHA-1、SHA-256、SHA-512)将输入分块处理,最终输出链值。给定 H(M),攻击者无需知道 M,即可计算 H(M || padding || append)。

影响: - API 签名伪造:sign = H(secret || data) 可构造 H(secret || data || padding || evil_data) 的有效签名,无需知道 secret - Web 应用:auth_token = MD5(secret_key || user_data) 可被扩展

不受影响的算法: - SHA-3(海绵结构)、BLAKE⅔ - HMAC 构造(H((K ⊕ opad) || H((K ⊕ ipad) || m)))天然免疫

防御: - 使用 HMAC 代替 H(secret || data) - 使用 SHA-3 或 BLAKE2 - 确保 secret 在末尾:H(data || secret)

3.2 碰撞攻击

原理:找到两个不同的消息 M1 ≠ M2 使得 H(M1) = H(M2)。

算法现状:

算法 碰撞复杂度 方法 实际可行性
MD5 2^18 (秒级) 王小云差分攻击 ✅ 完全可行
SHA-1 2^63 (约 1 万美元 GPU 算力) SHAttered (2017) ✅ 可行
SHA-256 2^128 生日攻击 ❌ 目前不可行
SHA-3 2128~2256 — ❌ 目前不可行

真实影响: - MD5 碰撞伪造 CA 证书(2008 年,Rogue CA) - SHA-1 碰撞伪造 PGP 密钥签名(2019 年,SHA-1 is a Shambles) - 恶意软件双胞胎:正常版本和恶意版本具有相同 MD5

3.3 彩虹表攻击

原理:预计算哈希值→明文的大型映射表,用空间换时间,快速查找哈希对应明文。

防御: - 加盐:每个密码独立随机的 salt,彩虹表重新计算成本极高 - 使用慢哈希:bcrypt / scrypt / Argon2 控制 CPU 和内存成本


四、协议层攻击

4.1 降级攻击(Downgrade Attack)

原理:中间人截获握手协商包,修改/删除高安全级别算法选项,迫使双方使用低安全算法。

真实案例: - POODLE(CVE-2014-3566):降级 TLS 到 SSLv3,利用 SSLv3 的填充弱点 - Logjam(CVE-2015-4000):降级 DHE 密钥交换到 512 位加密,可被 NSA 级算力破解 - FREAK(CVE-2015-0204):降级 RSA 密钥交换到 EXPORT 级 512 位 - SLOTH:降级到 MD5/RSA-MD5 签名,利用已知碰撞伪造握手

防御:TLS 1.3 通过 supported_versions 扩展和 FINISHED 消息完整性校验根本性解决。

4.2 重放攻击(Replay Attack)

原理:攻击者捕获合法通信并重放,达到欺骗系统的目的。

典型场景: - 捕获加密请求 → 重复发送 → 重复扣款 - 捕获认证 Token → 重放 → 绕过身份认证

防御:时间戳 + Nonce + 序列号组合使用,server 端验证唯一性。

4.3 时序攻击(Timing Attack)

原理:加密操作的执行时间依赖于秘密数据(密钥)的值,攻击者通过精确测量响应时间可推断密钥。

典型场景: - 字符串比较:strcmp(password, input) 中,逐字节比较,首个不匹配就返回,时间差异泄露正确前缀 - RSA CRT 泄露:Montgomery 乘法中密钥位为 1 时需额外规约,时序可泄露密钥位 - HMAC 时序:服务端验证 MAC 时的逐字节比较

防御:使用常量时间比较函数(如 hash_equals、CRYPTO_memcmp)。

4.4 CRIME / BREACH 压缩侧信道

攻击 年份 压缩层 目标
CRIME 2012 TLS Deflate 压缩 Session Cookie
BREACH 2013 HTTP 响应体 gzip 压缩 CSRF Token、Session ID
TIME 2013 HTTP 响应体 同 BREACH

原理:若明文包含攻击者可控部分和敏感部分(如 cookie),压缩算法会将相同字符串合并,导致压缩后长度变短。攻击者逐字符猜测敏感内容,观察压缩后密文长度变化即可确认猜测是否正确。

防御:禁用 TLS 压缩;敏感信息与用户输入分离(HTTP 头/body 分开压缩)。


五、常见评测/攻击工具

5.1 在线加解密 / 编码分析

工具 用途
CyberChef (gchq.github.io/CyberChef) 万能加解密与编码转换,强烈推荐
Ciphey 自动加解密识别,输入密文自动尝试解码
dcode.fr 在线密码学工具箱,支持数百种古典/现代算法
Boxentriq 密码分析在线平台
Hash Analyzer 哈希格式自动识别

5.2 哈希破解

hashcat

Bash
# 基本用法
hashcat -m 0 -a 0 hashes.txt wordlist.txt          # MD5,字典攻击
hashcat -m 1000 -a 3 hashes.txt ?l?l?l?l?d?d?d?d   # NTLM,掩码攻击

# 常用哈希模式 (-m)
#    0 = MD5
#  100 = SHA1
# 1400 = SHA256
# 1700 = SHA512
# 1000 = NTLM
# 3200 = bcrypt
# 11600 = 7-Zip
# 13721 = VeraCrypt
# -m 22000 = WPA-PBKDF2-PMKID+EAPOL

john the ripper

Bash
# 基本用法
john --wordlist=rockyou.txt hashes.txt
john --format=Raw-MD5 hashes.txt

# 查看已破解
john --show hashes.txt

常用哈希格式指定:

哈希类型 hashcat -m john --format=
MD5 0 Raw-MD5
SHA1 100 Raw-SHA1
SHA256 1400 Raw-SHA256
SHA512 1700 Raw-SHA512
NTLM 1000 NT
bcrypt 3200 bcrypt
WPA/WPA2 22000 wpapsk
ZIP 13600 zip
RAR 13000 rar
Keepass 13400 keepass

5.3 TLS/SSL 扫描

工具 用途
testssl.sh TLS/SSL 全面扫描,检查已知漏洞(POODLE、BEAST、Heartbleed 等)
sslscan 快速检测支持的加密套件和协议版本
nmap --script ssl-* Nmap SSL 检测脚本集
sslyze Python TLS 扫描器,支持 JSON 输出
cryptoLyzer 密码学参数深度分析(Diffie-Hellman 参数等)
OpenSSL s_client 手动 TLS 连接和诊断

常用 testssl.sh 命令:

Bash
testssl.sh https://example.com                         # 全量扫描
testssl.sh --each-cipher https://example.com           # 逐个密码套件测试
testssl.sh -p --fs --server-preference example.com     # 协议+前向安全性
testssl.sh -f -s -c --breach https://example.com       # 已知漏洞专项

5.4 密码分析专用

工具 用途
xortool XOR 密文分析,推断密钥长度和密钥
padding-oracle-attacker Padding Oracle 自动化攻击 Python 库
PORCUPINE 自动化 POODLE 漏洞利用
ROCA Detection Tool 检测 RSA 密钥是否受 Infineon ROCA 漏洞影响
RSACtfTool RSA 攻击工具集(Wiener、Boneh-Durfee、共模等)
yafu 大整数分解

5.5 Burp Suite 相关

扩展 用途
Burp Crypto 识别和枚举加密参数
SAMLRaider SAML 签名/加密攻击和重放
JSON Web Token Editor JWT 修改、算法混淆攻击
Java Deserialization Scanner 识别 Java 序列化数据用于 Padding Oracle

JWT 攻击技巧:

Text Only
{"alg": "HS256", "typ": "JWT"}

算法混淆攻击:
- 将 alg 从 RS256 改为 HS256
- 用服务器公钥作为 HMAC 密钥签名
- 服务器验证时可能接受 HS256

None 算法攻击:
- 将 alg 改为 "none"
- 删除签名部分
- 某些库的错误配置会接受无签名的 JWT

5.6 解密工具与库

工具/库 语言 用途
pyaes Python 纯 Python AES 实现,适合分析调试
pycryptodome Python 全功能密码学库
OpenSSL CLI CLI 通用加解密
Bash
# OpenSSL 常用加解密命令

# AES-256-CBC 解密
openssl enc -aes-256-cbc -d -in ciphertext.bin -out plaintext.bin -K <hexkey> -iv <hexiv>

# AES-256-ECB 加密(无 IV)
openssl enc -aes-256-ecb -e -in plain.txt -out cipher.bin -K <hexkey>

# Base64 解码 + AES 解密
echo "base64cipher" | base64 -d | openssl enc -aes-256-cbc -d -K <hexkey> -iv <hexiv>

# RSA 公钥加密
openssl rsautl -encrypt -inkey public.pem -pubin -in plain.txt -out cipher.bin

# RSA 私钥解密
openssl rsautl -decrypt -inkey private.pem -in cipher.bin -out plain.txt

# 从私钥导出公钥
openssl rsa -in private.pem -pubout -out public.pem

# 查看证书公钥
openssl x509 -in cert.pem -text -noout

# 计算 hash
echo -n "data" | openssl dgst -sha256

六、攻击速查矩阵

攻击 目标算法/模式 必要条件 产出
Padding Oracle CBC + PKCS#7 可区分的填充错误响应 完全解密
Bit Flipping CBC 已知明/密文对应位置 可控明文修改
ECB Byte-at-a-time ECB 已知前缀注入 + 独立密文块 完全解密未知后缀
ECB Cut-and-Paste ECB 已知明文密文块映射 伪造合法密文
Nonce Reuse (GCM) AES-GCM 相同 key+nonce 对 ≥2 次 认证密钥恢复 → 任意伪造
Nonce Reuse (CTR) AES-CTR 相同 key+nonce 对 ≥2 次 P1 ⊕ P2 泄露
Bleichenbacher RSA PKCS#1 v1.5 服务器返回 PKCS conforming 响应 恢复会话密钥
共模攻击 RSA 相同 N、gcd(e1,e2)=1 恢复明文
小指数广播 RSA e=3 同一 M 发给 ≥3 个不同 N 恢复明文
Wiener 攻击 RSA 小 d d < N^0.25 / 3 恢复私钥 d
ROCA RSA (Infineon) 受影响的智能卡/TPM 密钥 快速分解 N
ECDSA Nonce 重用 ECDSA 两次签名使用相同 k 恢复私钥 d
长度扩展 MD5/SHA1/SHA256 H(secret
Hash Collisions MD5/SHA-1 大量算力 伪造签名/证书
BEAST TLS 1.0 CBC 中间人 + JS 控制 恢复 session cookie
POODLE SSLv3 CBC 中间人 + JS 控制 恢复明文字节
CRIME/BREACH TLS + 压缩 攻击者可控输入 + 敏感数据同页面 恢复 CSRF/cookie
JWT alg=None JWT 服务端库未禁用 None 算法 绕过签名验证
JWT alg=HS256 JWT (RS256→HS256) 公钥泄露/可获取 用公钥签 HS256,服务器接受

七、防御 checklist

  1. 禁用 ECB 模式,最低使用 CBC + HMAC(Encrypt-then-MAC),推荐使用 AES-GCM / ChaCha20-Poly1305
  2. IV 必须由 CSPRNG 生成,每次加密不同,不可预测
  3. Nonce 绝不能重用(GCM/CTR),每次加密使用全新随机 Nonce
  4. 使用 AEAD 模式消除 Padding Oracle 攻击面
  5. 哈希用 HMAC,不用 H(secret || data) 防止长度扩展
  6. 密码存储用 bcrypt/scrypt/Argon2id,不用 SHA/MD5
  7. RSA 加密使用 OAEP 填充(非 PKCS#1 v1.5)
  8. RSA 签名使用 PSS 填充(非 PKCS#1 v1.5)
  9. 使用常量时间比较,防止时序侧信道
  10. TLS 配置禁用 SSLv2/SSLv3、RC4、EXPORT cipher、空压缩
  11. JWT 服务端强制指定算法(不使用 header 中的 alg)
  12. 仅使用标准库实现,绝不自行设计或实现密码学原语