CTF中的典型场景
在CTF密码学挑战中,常出现以下两类RSA低位泄露题型:
-
私钥低位泄露:给出的末位
-
素数低位泄露:给出或的末位
这类题目要求选手利用Coppersmith定理恢复完整密钥,以下是系统性解题方法。
一、私钥低位泄露攻击
攻击条件
已知:n
,e
,d_low = d mod 2^k
数学推导
-
由RSA定义:ed ≡ 1 mod ϕ(n)⇒ ed = 1 + kϕ(n)
-
代入ϕ(n) = n − (p+q) + 1构造方程:ed = 1 +k (n − (p + q) + 1)
-
通过已知的
d_low
建立方程,利用Coppersmith求解高位
实战代码(SageMath)
def recover_d(n, e, d_low, k_bits):
P.<x> = PolynomialRing(Zmod(e*n))
f = e*x - 1 + e*d_low
roots = f.small_roots(X=2^(n.nbits()-k_bits), beta=0.3)
if roots:
return roots[0] << k_bits | d_low
return None
# 示例参数
n = 0xabcdef...
e = 65537
d_low = 0x12345...
recovered_d = recover_d(n, e, d_low, k_bits=200)
二、素数低位泄露攻击
场景1:已知p的低k位
攻击步骤
-
设完整素数 p=phigh⋅2k+plow
-
构造方程 n ≡ 0 mod p ⇒ n ≡ 0 mod(phigh⋅2k+plow)
-
用Coppersmith求解p的高位
代码实现
def recover_p(n, p_low, k_bits):
P.<x> = PolynomialRing(Zmod(n))
f = x*2^k_bits + p_low
roots = f.monic().small_roots(X=2^(n.nbits()//2 - k_bits), beta=0.4)
if roots:
return roots[0]*2^k_bits + p_low
return None
场景2:已知p/q的高位(变形题)
# 已知p的高k位(如p = pHigh*2^m + x)
f = (p_high << m) + x
三、进阶技巧与优化
参数调整原则
-
X值选择:根据未知位数量设置上限,例如未知100位则
X=2^100
-
beta参数:通常取0.4-0.49(需满足beta ≤ 未知位数/总位数)
-
多解处理:遍历可能的根进行验证
加速技巧
-
使用
defund/coppersmith
等优化算法 -
尝试不同beta值组合
-
优先验证低位是否符合模运算特性
四、典型CTF例题解析
例题:LostPrime
题目给出:
n = 124373462456753234876885220553527371514412189273708387803379740454747329757646714507732149997806416311212770832817567344597369013077503761564730637292822190898605501605620096233619021437529457696534197112644821519151834514614442850344611947221582810814021437512623722573900305582615607466805014405632112212089
e = 65537
p_low = 0x635f726d21645d1d # 已知p的最后64位
ciphertext = 0x8af11...dac3 # 密文
解题思路
-
目标:通过已知p的低64位恢复完整p,进而分解n解密
-
关键点:
-
n是1024位RSA,即p/q各512位
-
已知p的低64位(占总长度的12.5%)
攻击步骤
Step1:构造多项式
设完整素数
p=x⋅264+plowp=x⋅264+plo__w,其中x为未知高位
建立方程:
n≡0modp⇒n=p⋅q=(x⋅264+plow)⋅qn≡0modp⇒n=p⋅q=(x⋅264+plo__w)⋅q
Step2:SageMath求解
n = 124373...089
p_low = 0x635f726d21645d1d
k_bits = 64
# 构造模方程
P.<x> = PolynomialRing(Zmod(n))
f = x*2^k_bits + p_low
root = f.monic().small_roots(X=2^(512-k_bits), beta=0.4) # X=2^(512-64)
if root:
p = int(root[0])*2^k_bits + p_low
assert n % p == 0, "Recovery Failed!"
q = n // p
Step3:密钥生成与解密
phi = (p-1)*(q-1)
d = inverse_mod(e, phi)
flag = pow(ciphertext, d, n)
print(bytes.fromhex(hex(flag)[2:]))
参数分析
-
X=2^(512-64)
:x的取值范围上限(高位未知部分) -
beta=0.4
:根据经验公式选择(需满足beta ≤ 未知位数/总位数) -
monic()
:将多项式首系数归一化提升求解效率
易错点提醒
-
若未找到解,尝试:
-
调整beta值(0.3-0.49)
-
检查p_low是否正确(常见陷阱:题目可能给出十六进制但实际是十进制)
-
多解验证:当small_roots返回多个解时,需逐个检查是否满足n%p==0
五、防御方案
-
密钥存储:使用HSM保护私钥完整位
-
白盒加密:避免侧信道泄露
-
参数检查:生成密钥后验证d>2n.bitlength()/2
结语
掌握Coppersmith攻击方法需要深入理解模方程构造技巧,建议通过CTF实战平台(如CryptoHack)进行专项训练。
记住:数学是密码学的灵魂,而自动化工具是解题的利剑。
注:鼎星安全有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
原文始发于微信公众号(鼎新安全):CTF中的RSA低位攻击:从理论到实战
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论