其他的题目都太简单了,这一道题虽然也不难,但是由于非预期解的存在,还是挺有意思的

RSA2

Task

from Crypto.Util.number import getStrongPrime, bytes_to_long
from gmpy2 import powmod
from secret import flag

p = getStrongPrime(512)
q = getStrongPrime(512)
r = getStrongPrime(512) * p
n = p * q * r
t1 = 2334 + r - r // p - p
t2 = 23334 + r - r // p - p
test_1 = powmod(q, t1, r)
test_2 = powmod(q, t2, r)

e = 65537
m = bytes_to_long(flag)
c = powmod(m, e, n)
print(f"n = {n}")
print(f"c = {c}")
print(f"e = {e}")
print(f"r = {r}")
print(f"test_1 = {test_1}")
print(f"test_2 = {test_2}")

"""
n = 19394374939804636077298787696999145651388601917322114895642838853953381808240702298158075667836933844491914300462200498201232502597820471480278104873709079654383571733982600793391645736041575554416761411190577666894319909094358212628600451699873050386633961355953081164797613802471503835972928156332452586946123449475018268744050878129654089828539569290163248669910546474863971193248913060301042961297573273735567035638484842640891102000757796883117449143733645075205787306969545619475615329292516687937499869527048405181860848871040143454231725384444493671341489194232832604336747339981987968136805889988687471700689
c = 3445029509586789808191705086645892423344577895037990571917352198546103689956715444033789264619614928374173476257167068005615154238272256059206608521783259242336753735756270112683064185174154799787961620809472112672118869269531775498552913966749136960082148806701372215067784028138932161876481489483873874799577724564723536348878312087744205685152618944049898188467560333943868310819003549830041266285452470975843082633880273304056420983351380067924031473031902543251747872634679470807321088893876373614041197021272507490311894156474653766409806436771639703723056721686546437267761800664890347807938625483929875463817
e = 65537
r = 137186922017951798551013401031704441055292816273244383207330822587665397547633114179564214318161419547692944354372913721036795205992346900855775319896575433470493561754043711065187018521093256306861110861619139917879019066158769928044089694954100132993743545321108599987390965031813714252751340253063380122781  
test_1 = 10484222645942880569836346075211281500874316946773201245651921797050891795748018447890023984042009352443993529052624578259137283707622203132903778636427100673857236327880267380370130055336876593685230110403102135481150897000578831309789840644914684399062683490015265131603393965109484777590220067155254662724
test_2 = 46456546765497070754887354077605248455173445868539256339074654174920046820647882073337928470491562197950314697051806785137505130712091646483422595416843622895712210098782991926220638941734115040651715763329324337370957581802656073016916306620765962524561139196288970336270965816673108758049003178870509619277
"""

Think

看题目揣测出题人的意图,对t1和t2模一个p,得出t1 = 2333 mod p,t2 = 23333 mod p。看这种情况大胆用2333和23333替换t1和t2对其进行共模攻击,可以解出来q。然后解出p得出flag。

当然,这题还有一个非预期解。n//r = p * q。r = p * q。走一个gcd(n//r,r)就能求出来p,同样成功分解了n。

Exp

from Crypto.Util.number import *
from gmpy2 import invert

n = 19394374939804636077298787696999145651388601917322114895642838853953381808240702298158075667836933844491914300462200498201232502597820471480278104873709079654383571733982600793391645736041575554416761411190577666894319909094358212628600451699873050386633961355953081164797613802471503835972928156332452586946123449475018268744050878129654089828539569290163248669910546474863971193248913060301042961297573273735567035638484842640891102000757796883117449143733645075205787306969545619475615329292516687937499869527048405181860848871040143454231725384444493671341489194232832604336747339981987968136805889988687471700689
c = 3445029509586789808191705086645892423344577895037990571917352198546103689956715444033789264619614928374173476257167068005615154238272256059206608521783259242336753735756270112683064185174154799787961620809472112672118869269531775498552913966749136960082148806701372215067784028138932161876481489483873874799577724564723536348878312087744205685152618944049898188467560333943868310819003549830041266285452470975843082633880273304056420983351380067924031473031902543251747872634679470807321088893876373614041197021272507490311894156474653766409806436771639703723056721686546437267761800664890347807938625483929875463817
e = 65537
r = 137186922017951798551013401031704441055292816273244383207330822587665397547633114179564214318161419547692944354372913721036795205992346900855775319896575433470493561754043711065187018521093256306861110861619139917879019066158769928044089694954100132993743545321108599987390965031813714252751340253063380122781
test_1 = 10484222645942880569836346075211281500874316946773201245651921797050891795748018447890023984042009352443993529052624578259137283707622203132903778636427100673857236327880267380370130055336876593685230110403102135481150897000578831309789840644914684399062683490015265131603393965109484777590220067155254662724
test_2 = 46456546765497070754887354077605248455173445868539256339074654174920046820647882073337928470491562197950314697051806785137505130712091646483422595416843622895712210098782991926220638941734115040651715763329324337370957581802656073016916306620765962524561139196288970336270965816673108758049003178870509619277

def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)

e1 = 2333
e2 = 23333
c1 = test_1
c2 = test_2

g, s1, s2 = egcd(e1, e2)

if g != 1:
    raise ValueError("false")

c1_inv = pow(c1, s1, r) 
c2_inv = pow(c2, s2, r) 

q = c1_inv * c2_inv % r
p = n // (q * r)
k = r // p
phi = p*(p - 1) * (q - 1) * (k - 1)
d = invert(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))

#------------>以下是非预期解脚本<-----------------
from Crypto.Util.number import long_to_bytes, GCD

n = 19394374939804636077298787696999145651388601917322114895642838853953381808240702298158075667836933844491914300462200498201232502597820471480278104873709079654383571733982600793391645736041575554416761411190577666894319909094358212628600451699873050386633961355953081164797613802471503835972928156332452586946123449475018268744050878129654089828539569290163248669910546474863971193248913060301042961297573273735567035638484842640891102000757796883117449143733645075205787306969545619475615329292516687937499869527048405181860848871040143454231725384444493671341489194232832604336747339981987968136805889988687471700689
c = 3445029509586789808191705086645892423344577895037990571917352198546103689956715444033789264619614928374173476257167068005615154238272256059206608521783259242336753735756270112683064185174154799787961620809472112672118869269531775498552913966749136960082148806701372215067784028138932161876481489483873874799577724564723536348878312087744205685152618944049898188467560333943868310819003549830041266285452470975843082633880273304056420983351380067924031473031902543251747872634679470807321088893876373614041197021272507490311894156474653766409806436771639703723056721686546437267761800664890347807938625483929875463817
r = 137186922017951798551013401031704441055292816273244383207330822587665397547633114179564214318161419547692944354372913721036795205992346900855775319896575433470493561754043711065187018521093256306861110861619139917879019066158769928044089694954100132993743545321108599987390965031813714252751340253063380122781
p = GCD(n//r, r)
#甚至这时候直接用print(long_to_bytes(pow(c, pow(65537, -1, p-1), p)))就能出flag
q = n//(r * p)
k = r // p
phi = p*(p - 1) * (q - 1) * (k - 1)
d = invert(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))


flag{469c3244-1a40-4372-9aae-bca0aa75c583}


为了终将忘却的纪念