RSA初级题,记录一下。
源码:
import libnum
from Crypto.Util import number
from secret import flag
size = 256
e = 65537
p = number.getPrime(size)
q = number.getPrime(size)
avg = (p+q)/2
n = p*q
m = libnum.s2n(flag)
c = pow(m, e, n)
print('n = %d' % n)
print('avg = %d' % avg)
print('c = %d' % c)
'''
n = 5700102857084805454304483466349768960970728516788155745115335016563400814300152521175777999545445613444815936222559357974566843756936687078467221979584601
avg = 75635892913589759545076958131039534718834447688923830032758709253942408722875
c = 888629627089650993173073530112503758717074884215641346688043288414489462472394318700014742820213053802180975816089493243275025049174955385229062207064503
'''
老套路,需要对 n
进行因子分解从而解密。
分析一下,因为
a
v
g
=
p
+
q
2
avg=\frac{p+q}{2}
avg=2p+q
则有
p
2
−
2
p
×
a
v
g
=
p
2
−
p
2
−
p
q
=
−
n
p^2-2p \times avg = p^2 - p^2 - pq=-n
p2−2p×avg=p2−p2−pq=−n
同理
q
2
−
2
q
×
a
v
g
=
q
2
−
q
2
−
p
q
=
−
n
q^2-2q \times avg = q^2 - q^2 - pq=-n
q2−2q×avg=q2−q2−pq=−n
于是可知 p,q
是方程
x
2
−
2
x
×
a
v
g
+
n
=
0
x^2-2x \times avg +n=0
x2−2x×avg+n=0的解,老套路利用韦达定理求解即可。
最终exp:
#sage
from Crypto.Util.number import *
from gmpy2 import iroot
n = 5700102857084805454304483466349768960970728516788155745115335016563400814300152521175777999545445613444815936222559357974566843756936687078467221979584601
avg = 75635892913589759545076958131039534718834447688923830032758709253942408722875
c = 888629627089650993173073530112503758717074884215641346688043288414489462472394318700014742820213053802180975816089493243275025049174955385229062207064503
e = 65537
z = var('z')
delta = (2*avg)**2 - 4*n
if iroot(delta, 2)[1] == True:
sol = solve(z**2-2*avg*z+n==0, z, solution_dict=True)
a, b = int(z.subs(sol[0])), int(z.subs(sol[1]))
a, b = [a, b] if a > b else [b, a]
p, q = a, b
assert p * q == n
phi = (p-1) * (q-1)
d = pow(e, -1, phi)
m = int(pow(c, d, n))
print(long_to_bytes(m))