RSA2
题目
e = 65537
n=248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp=905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657
c=140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751
解题思路
题目给出了e,n,dp,c,求解明文
常规的思路是将n分解为p和q,但是这里给的n有309位之长,直接爆破求解显然难度很大
可以关注到题目所给的dp,看一下这个dp怎么用
进行一下公式推导:
dp = d % (p-1) ①
d = dp + k1 * (p-1) ②
d * e = 1 + k2(p-1)(q-1) ③
把②代入③,得到
e * (dp + k1(p-1)) = 1 + k2(p-1)(q-1)
为把系数k消掉,两边同时对(p-1)取模
e * dp % (p - 1) = 1
e * dp = 1 + k(p - 1)
由③就可以导出p与e、dp的关系
p - 1 = (e * dp - 1) / k ④
但是这里引入了一个系数k,这个k该怎么处理呢
④变形一下有
k = (e * dp - 1) / (p-1)
又由①,可以判断出dp < (p-1)
所以可以得到k = (e * dp - 1) / (p-1) < e
e = 65537,因此k的范围有了约束
至此,根据④式可以求解p
具体思路如下:
1.遍历k,k的范围是(1-65537)
2.判断(e * dp - 1)能否整除k,若能,则p = (e * dp - 1) / k + 1
3.判断n能否整除p,若能,则q = n / p
4.判断p,q是否都为素数,若都通过素性检验,则n成功分解出p和q
5.有了p、q之后,就可以计算出私钥d,进行解密得到flag
附上代码:
import gmpy2
import binascii
e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657
c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751
tmp = e * dp -1
#根据联立条件有: e*dp = 1 + k(p-1),故求解p的式子为:(p-1) = (e*dp-1) / k
for k in range(1, e):#因为K上限只到e,故遍历求解
if tmp % k == 0:#验证(p-1)是否为整除结果
p = (tmp // k) + 1
if n % p == 0:#验证p能否被n整除
q = n // p
if gmpy2.is_prime(p) and gmpy2.is_prime(q):#验证求解的p, q是否为素数
# print(k)
print("N的分解结果为 : ")
print("%d = %d * %d" % (n, p, q))
break
d = gmpy2.invert(e,(p-1)*(q-1)) # 求逆元,de = 1 mod fai(n)
m = gmpy2.powmod(c,d,n)# 幂取模,求明文
m = hex(m)[2:]
print("密文数据为:0x" + m)
flag = binascii.unhexlify(m)
print(flag)
flag
flag{wow_leaking_dp_breaks_rsa?_98924743502}