原题
from Crypto.Util.number import *
from math import gcd
from secret import flag
def gen_key(nbits, gamma):
g = getPrime(int(nbits * gamma))
alpha = 0.5 - gamma
while True:
a = getPrime(int(alpha * nbits))
p = 2 * g * a + 1
if isPrime(p):
break
while True:
b = getRandomNBitInteger(int(alpha * nbits))
q = 2 * g * b + 1
h = 2 * g * a * b + a + b
if isPrime(q) and isPrime(h) and gcd(a, b) == 1:
return p*q,a,g
else:
continue
n,a,g = gen_key(1024, 0.05)
e = 65537
c = pow(bytes_to_long(flag),e,a*g)
print(n,c,a)
'''
n=36535558847082719901201561031181835346574576610950713924924272947759193576365817762980927638691696601293089537315055413746788190208875234794229119049056299551864869870291634941246362436491006904347559559494705922259007299126640817275929491680601926404543198957206717290905220235571289759182878331893962038379
c=532997872940452282189043430008002793694788439822465302532208754231005799057972378308576109082463996551992533174546386979606697890310597738637156771564229
a=2694858406312563434474553988904403597551484373358339092528913028454100111881368126493990657117571672510331411186745639563619323775673115439
'''
解题过程
其实挺简单的,当初一看500分,觉得不是我能动的题,下来复盘了一下后悔没细看
过程如下
p*q = 2g(a+b) + 4ab*g**2 +1
而a+b+2gab == h
化简得到
p*q-1 = 2gh
本题的公钥是(e,a*g)
我们可以考虑用p*q-1 = 2gh
分解得到g
n = (n-1) // 2
因为g是51位
的
h是约为972位
的
相差很大可以用yafu分解或者factordb查一下
得到
g = 1346104232461691
h = 13570850594633462506426369052182298554140635599543685835372377476383038708650421475723391142118956001358520246769650699398490037618758005241062608387057439283872260149565854577827352267289963736282502923131251179400580891491236925451166755184695335564693793568286112036468975877609637392241679
于是脚本如下
from Crypto.Util.number import *
import gmpy2
c = 532997872940452282189043430008002793694788439822465302532208754231005799057972378308576109082463996551992533174546386979606697890310597738637156771564229
a = 2694858406312563434474553988904403597551484373358339092528913028454100111881368126493990657117571672510331411186745639563619323775673115439
g = 1346104232461691
e = 65537
d = gmpy2.invert(e,(g-1)*(a-1))
print(long_to_bytes(pow(c,d,a*g)))
# b'flag{p01la4d_rHo_a1gOr1thM_r1gh4}'
后来做到了羊城杯2021的一道类似的rsa
才知道这是Common Prime RSA
常见的攻击方法有
1.修改Pollard’s rho方法分解n
2.知道a,b
3.知道g
4.分解n-1
后记
痛失线下赛,要哭哭惹