密码学攻击手法
密码学攻击手法¶
一、分组密码攻击¶
1.1 ECB 模式攻击¶
原理:ECB 模式下,相同的明文分组产生相同的密文分组,密文保留了明文的模式特征。
攻击方法:
- 块重排攻击:截获密文后,将密文块重新排列组合,解密后得到语义被篡改的明文。
- Byte-at-a-time 解密:在未知明文之前注入可控前缀,利用分块边界逐步爆破未知明文的每个字节。
- Cut-and-Paste 攻击:从已知密文中剪切一个特定块,拼接到目标密文中,实现伪造(如将特权信息块嫁接到低权限用户密文中)。
实际案例:Adobe 2013 密码泄露使用 ECB 加密密码提示,相同密码提示生成相同密文块而被分析。
1.2 CBC Padding Oracle 攻击(重点)¶
原理:PKCS#7 填充要求明文末尾必须是合法的填充值(如 \x02\x02 或 \x05\x05\x05\x05\x05)。服务器解密后校验填充是否合法,若返回不同错误信息,攻击者可利用此 Oracle 逐个字节恢复明文。
攻击步骤:
假设密文分组: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.axdPadding 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。
应用场景:
原始明文:{"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 重用:
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 两两互质),攻击者可:
条件:小指数 e + 至少 e 组密文 + 同一明文 + 不同模数。
防御:使用 OAEP 填充使每次加密结果不同;使用 e=65537。
2.3 共模攻击¶
原理:同一明文 M 用同一模数 N 但不同指数 e1、e2 加密(gcd(e1, e2)=1),攻击者无需分解 N 即可恢复明文。
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。
条件: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 重用,攻击者可直接恢复私钥。
两个签名使用相同 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
# 基本用法
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
# 基本用法
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 命令:
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 攻击技巧:
{"alg": "HS256", "typ": "JWT"}
算法混淆攻击:
- 将 alg 从 RS256 改为 HS256
- 用服务器公钥作为 HMAC 密钥签名
- 服务器验证时可能接受 HS256
None 算法攻击:
- 将 alg 改为 "none"
- 删除签名部分
- 某些库的错误配置会接受无签名的 JWT
5.6 解密工具与库¶
| 工具/库 | 语言 | 用途 |
|---|---|---|
| pyaes | Python | 纯 Python AES 实现,适合分析调试 |
| pycryptodome | Python | 全功能密码学库 |
| OpenSSL CLI | CLI | 通用加解密 |
# 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¶
- 禁用 ECB 模式,最低使用 CBC + HMAC(Encrypt-then-MAC),推荐使用 AES-GCM / ChaCha20-Poly1305
- IV 必须由 CSPRNG 生成,每次加密不同,不可预测
- Nonce 绝不能重用(GCM/CTR),每次加密使用全新随机 Nonce
- 使用 AEAD 模式消除 Padding Oracle 攻击面
- 哈希用 HMAC,不用
H(secret || data)防止长度扩展 - 密码存储用 bcrypt/scrypt/Argon2id,不用 SHA/MD5
- RSA 加密使用 OAEP 填充(非 PKCS#1 v1.5)
- RSA 签名使用 PSS 填充(非 PKCS#1 v1.5)
- 使用常量时间比较,防止时序侧信道
- TLS 配置禁用 SSLv2/SSLv3、RC4、EXPORT cipher、空压缩
- JWT 服务端强制指定算法(不使用 header 中的 alg)
- 仅使用标准库实现,绝不自行设计或实现密码学原语