密码学 CTF 挑战:古典与现代密码破解
密码学 CTF 挑战:古典与现代密码破解
简介
密码学是 CTF(Capture The Flag)竞赛中的核心类别,考验选手对信息加密、解密、分析和漏洞利用的能力。本教程将从零开始,带你掌握古典密码和现代密码的常见攻击方法,无论你是刚接触 CTF 的新手,还是希望系统梳理知识的晋级者,都能从中获益。
教程分为四大部分:
- 古典密码破解:替换密码、移位密码、维吉尼亚密码等
- 现代密码破解:RSA、AES、ECC 的典型弱点
- 实战工具与脚本:常用库与在线资源
- 综合案例分析:典型题目的完整解决思路
古典密码破解
古典密码是 CTF 中的常客,通常考察选手的观察力、频率分析和模式识别能力。其安全性完全依赖于算法的保密,在现代计算力面前不堪一击。
单表替换密码
凯撒密码:每个字母按固定偏移量移位。
破解方法:暴力枚举 25 种偏移,或通过词频分析。
例题:密文 Khoor, Zruog!
解密:偏移 3 即可得到 Hello, World!。
Python 代码片段:
def caesar_decrypt(cipher, shift):
result = ''
for c in cipher:
if c.isalpha():
base = ord('A') if c.isupper() else ord('a')
result += chr((ord(c) - base - shift) % 26 + base)
else:
result += c
return result
print(caesar_decrypt('Khoor, Zruog!', 3))
简单替换密码:每个字母唯一映射到另一个字母,密钥空间 26!。
破解方法:频率分析。英语中字母 e、t、a、o、i、n 出现频率最高,常见双字母组合 th、he、in,三字母组合 the、and。使用工具如 quipqiup 或自己编写爬山算法。
仿射密码
加密函数:E(x) = (ax + b) mod 26,其中 a 与 26 互质。
密钥空间很小(a 可取 1,3,5,7,9,11,15,17,19,21,23,25),直接爆破即可。
已知明文攻击:若有一对明文-密文,可直接建立方程组求解 a、b。
维吉尼亚密码
多表替换,由密钥决定每一字母的偏移。
破解步骤:
- 确定密钥长度:Kasiski 测试(寻找重复序列的间距最大公约数)、重合指数法。
- 恢复密钥:将密文按密钥长度分组,每组退化成一个凯撒密码,对每组进行频率分析,最高频字母假设对应 e,即可反推偏移值。
在线工具推荐:DCode Vigenère Tool,或使用 Python cryptanalysis 库。
栅栏密码与换位密码
栅栏密码:按行排列后按列读取。
例:TBOARPX 深度 2 → 写出斜线排列,还原得 TRAPBOX。
列置换密码:用关键字决定列读取顺序。破解思路:尝试常见密钥长度,分段重组明文,看单词是否可读。
工具:在线栅栏密码破解器,或编写脚本穷举深度/列数。
现代密码破解
现代密码的安全性基于数学难题,但在 CTF 中常因实现错误、参数过弱、信息泄露而存在攻击面。
RSA 攻击面汇总
RSA 是出题最多的公钥密码,攻击向量丰富。核心公式:n = p * q, ed ≡ 1 mod φ(n),其中 φ(n) = (p-1)(q-1)。
模数分解攻击
当 n 过小、p 和 q 差距过大、或使用相同 n 重用时:
- 小 n 直接分解:使用 factordb.com 或 yafu 工具。
- Fermat 分解:当 p 和 q 相近时,
n = (a-b)(a+b),快速找到 a 和 b。 - 共享素数攻击:两个用户使用相同的 p 或 q 生成 n,求两 n 的最大公约数可得 p。
低加密指数攻击
e 很小时(如 e=3),若明文 m 也很小,使得 m^e < n,则直接对密文开 e 次方根即可。
若 m^e 略大于 n,但仍在合理范围,可使用 小指数广播攻击:同一明文用不同 n(互质)加密,收集 e 组密文后用中国剩余定理。
共模攻击
相同明文 m 用两个互质的 e1、e2 在同一个 n 下加密,得到密文 c1, c2。通过扩展欧几里得算法可恢复 m,不需要私钥。
维纳攻击 (Wiener's Attack)
当私钥 d 很小(d < N^(1/4)/3)时,可利用连分数逼近 e/N 恢复 d。工具:owiener Python 包。
部分信息泄露
- 私钥文件泄露部分比特(如低位的 d )可用 Coppersmith 攻击恢复。
- p 高位或低位已知:使用 SageMath 的 coppersmith 方法解多项式方程。
对称密码弱点
AES 实现问题:
- ECB 模式:相同明文块产生相同密文块,可造成信息泄露。攻击:字节反转、块重放、拖库检测。
- CBC/CTR 模式的 IV 重用或可预测:导致明文异或 XOR 泄露。
- Padding Oracle 攻击:服务端返回填充错误与否,可逐字节解密任意密文。
流密码:若密钥流重用(如 RC4 相同密钥加密两条明文),则 C1 XOR C2 = P1 XOR P2,配合已知明文或 crib dragging 恢复明文。
哈希长度扩展攻击:对于 H(secret + message) 结构的 MAC,知道 message 和长度,可构造新消息和有效 MAC。常见于 MD5、SHA1、SHA2 但 SHA3 免疫。
椭圆曲线密码 (ECC) 入门攻击
ECC 安全性基于离散对数困难,CTF 中常出现:
- Pohlig-Hellman 攻击:阶为平滑整数(由小因子乘积构成),可分别计算各子群离散对数,再 CRT 合并。例:曲线阶为素数但含小因子则不安全。
- Smart 攻击:在异常曲线(阶等于基域素数)上,利用 p-adic 提升在多项式时间内求解离散对数。
- 非法曲线攻击:不验证点是否在给定曲线上,可能允许发送不同 curve 上的点,导致安全降级。
工具:SageMath 内置大量曲线运算函数,可直接调用 discrete_log 配合参数。
常用工具与脚本库
Python 密码库
- PyCryptodome:RSA, AES, 哈希等现代密码实现。
- gmpy2:大整数运算,提供
invert,iroot,gcdext等高效函数。 - pwnlib (pwntools):集成许多 CTF 辅助功能,包括
xor等。 - sympy:因式分解小整数。
专用破解工具
- RsaCtfTool:自动检测并攻击弱 RSA 密钥,集成分解、维纳、低指数等多种攻击。
- xortool:分析 XOR 加密文件,猜测密钥长度并解密。
- Ciphey:使用自然语言处理全自动识别并解密古典密码。
- CyberChef:浏览器端“瑞士军刀”,拖拽式操作,适合快速编码/解码。
在线服务
- factordb.com:已知大数分解数据库。
- dcode.fr:涵盖大量古典密码的识别与破解。
- quipqiup.com:快速破解单表替换密码。
实战案例分析
案例一:古典密码组合
题目描述:给出密文 UGFzc3dvcmQ6IG5v 以及提示“Base64 后凯撒”。
解题思路:
- 观察字符串末尾有
=,Base64 特征,先用 Base64 解码得到Password: no。 - 但这似乎不完整,考虑是先凯撒后 Base64?尝试将密文进行凯撒位移后再 Base64,或者直接分析 Base64 解码内容?根据提示“Base64 后凯撒”,说明原文经过凯撒加密,再 Base64 编码。
- 将密文 Base64 解码得到字节序列:
Password: no,这显然不应是凯撒加密后的结果,因为包含标点和单词。说明提示可能是“先 Base64 解码,结果仍是凯撒”,重新解读:原文先凯撒位移,然后 Base64 编码。我们现在拿到密文,需要逆操作:Base64 解码得到中间值Password: no,再对它进行凯撒解密。尝试 Caesar 偏移,发现Password: no偏移后可得有意义明文?若偏移 13(ROT13)得到Cnfgrffbq: ab,不合理。也许提示是指“Base64 和凯撒结合”,具体还需要根据 flag 格式猜测。 - 另一种思路:直接将
UGFzc3dvcmQ6IG5v当作凯撒密文处理,对每个字符移动,但包含大小写字母和数字,不符合凯撒范围。最终发现先 Rot13 再 Base64 会得到有意义结果?其实这个案例改编自真实比赛:因为Password: no是凯撒密文,ROT13 后正好是Cnfgrffbq: ab,看起来无意义,但真正的 flag 藏在 Base64 的内容里。通常这类题会将 flag 嵌入多层编码,多尝试。 (为了展示流程,简化:事实上UGFzc3dvcmQ6IG5vBase64 解码为Password: no,再 ROT13 得Cnfgrffbq: ab,不符合预期。可能是出题者故意绕,需要把no替换为 flag 格式?常见解法是观察 length。此处不做无意义推测。)
正确示范:针对类似题目,梳理操作顺序,用 CyberChef 的 Magic 模块自动识别多层编码,可快速解出。
案例二:弱 RSA 密钥攻击
题目:给定 n, e, c,其中 e = 3,c 值较小。
分析:很可能 m^3 < n,直接开三次方根。
Python 解法:
from gmpy2 import iroot
import libnum
c = 15369425531762348743
e = 3
m, is_perfect = iroot(c, e)
if is_perfect:
print(libnum.n2s(int(m))) # 转换为字节
else:
print("不是完全立方,尝试小指数广播或其他攻击")
案例三:ECB 模式字节反转
情景:网站使用 AES-ECB 加密 Cookie 如 user=guest,如何提升为 admin?
攻击:注册一个可控用户名,使 username 恰好占据一个明文块,然后用另一个块的密文替换 guest 块。例如注册 aaaaaaaaaaadmin,抓取密文中对应 admin 的块,替换到 cookie 中 user=guest 后的块,实现权限提升。
总结
密码学 CTF 挑战从古典到现代,核心是理解密码算法的数学本质与实现弱点:
- 古典密码重在模式识别和频率分析,自动化工具可解决大部分。
- RSA 攻击重点在分解、低指数、共模、维纳攻击等,要熟练掌握 gmpy2 和 RsaCtfTool。
- 对称密码重点在模式的副作用(ECB、Padding Oracle)和密钥重用。
- 持续积累常见漏洞模式和脚本库,遇到新题能快速匹配攻击模型。
保持好奇,勤于动手,每解一道题都尽量理解背后的原理。推荐阅读 PyCryptodome 文档和 CTF Wiki 的密码学章节。比赛时,不妨先用 CyberChef 或 Ciphey 快速试探,再根据返回信息深入攻击。