题目
附件
观察附件,发现给了两组e,两组c,两组n,这里p1,p2相等,下面就以p代之。
初步想法是分别解两组n,e,c,然后再整合两个flag,得到最终的flag,但算到d的逆元时求不出来,原因是e与phi不互素,所以换一个思路试试。
这里设
根据rsa加解密运算
phi = (p-1)*(q-1)
可得出
由Euler(欧拉定理)可知
这里ed=k*phi+1
结合解密运算,所以有
即
ed=k*phi+1=a*b*d
又因为
所以只需求出a在phi下的逆元bd,即可求出m^b的解,因为gcd(e1,e2)=14,所以这里的b就等于14。分别求一下m1,m2,代码如下:
n1 = p*q1
n2 = p*q2
phi1 = (p-1)*(q1-1)
phi2 = (p-1)*(q2-1)
b = gmpy2.gcd(e1,e2)
a1 = e1//b
a2 = e2//b
bd1 = gmpy2.invert(a1,phi1)
bd2 = gmpy2.invert(a2,phi2)
m1 = pow(c1,bd1,n1)
m2 = pow(c2,bd2,n2)
这里我一开始是直接将结果m1,m2开14次方,然后输出flag,但发现行不通,我个人认为应该是开方不完全的原因,换句话说,就是m1,m2开14次方不是整数,python里对其取了整数部分,但转字符会出问题。
所以这里只能继续想其他办法,根据附件可得以下式子
c ≡ c1 ≡ m1 mod p
c ≡ c1 ≡ m1 mod q1
c ≡ c2 ≡ m2 mod p
c ≡ c2 ≡ m2 mod q2
这里可以利用中国剩余定理,结合c1,c2求出特解c
取q1,q2两项,取法(看mod左边,相同的两项m1只能取一个,且取的mod右边的数互素),取法仅个人理解。
就可以得到一个新的密文c,这里的e依旧是14,n=q1*q2。
这里直接使用python中libnum库的crt来解
c = solve_crt([m1, m2], [q1, q2])
这里解出来的也是m^14,与上面不同的是,这里就一个,当然,这里依旧不能直接开方求,原因和上面一样,这里把14分成2*7,将m^2看成整体m,所以这里的e就成了7,求7在(q1-1)*(q2-1)下的逆元,也就是d,常规rsa即可解出flag
n = q1 * q2
f = (q1 - 1) * (q2 - 1)
d2 = gmpy2.invert(7, f)
m = pow(c, d2, n)
msg = gmpy2.iroot(m, 2)[0]
print(long_to_bytes(msg).decode('utf-8'))
完整代码如下:
import gmpy2
from Crypto.Util.number import *
from libnum import *
e1 = 14606334023791426
e2 = 13813369129257838
p =
q1 =
q2 =
c1 =
c2 =
n1 = p*q1
n2 = p*q2
phi1 = (p-1)*(q1-1)
phi2 = (p-1)*(q2-1)
b = gmpy2.gcd(e1,e2)
a1 = e1//b
a2 = e2//b
bd1 = gmpy2.invert(a1,phi1)
bd2 = gmpy2.invert(a2,phi2)
m1 = pow(c1,bd1,n1)
m2 = pow(c2,bd2,n2)
'''
结合c1,c2求一特解c
c ≡ c1 ≡ m1 mod p
c ≡ c1 ≡ m1 mod q1
c ≡ c2 ≡ m2 mod p
c ≡ c2 ≡ m2 mod q2
取q1,q2两项,取法(看mod左边,相同的两项m1只能取一个,且取的mod右边的数互素)
'''
c = solve_crt([m1, m2], [q1, q2])
n = q1 * q2
f = (q1 - 1) * (q2 - 1)
d2 = gmpy2.invert(7, f)
m = pow(c, d2, n)
msg = gmpy2.iroot(m, 2)[0]
print(long_to_bytes(msg).decode('utf-8'))
结果:
成功拿到flag!!!,顺便补充一点,之所以我在输出里加了一个utf-8的解码,是因为flag里有这个编码。