[GWCTF 2019]babyRSA | NSSCTF
观察主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import hashlib import sympy from Crypto.Util.number import *
flag = 'GWHT{******}' secret = '******'
assert(len(flag) == 38)
half = len(flag) / 2
flag1 = flag[:half] flag2 = flag[half:]
secret_num = getPrime(1024) * bytes_to_long(secret)
p = sympy.nextprime(secret_num) q = sympy.nextprime(p)
N = p * q
e = 0x10001
F1 = bytes_to_long(flag1) F2 = bytes_to_long(flag2)
c1 = F1 + F2 c2 = pow(F1, 3) + pow(F2, 3) assert(c2 < N)
m1 = pow(c1, e, N) m2 = pow(c2, e, N)
output = open('secret', 'w') output.write('N=' + str(N) + '\n') output.write('m1=' + str(m1) + '\n') output.write('m2=' + str(m2) + '\n') output.close()
|
给了N,m1,m2
1 2 3 4
| N=636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163 m1=90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239 m2=487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546
|
此处p和q是两个相邻的素数
1 2
| p = sympy.nextprime(secret_num) q = sympy.nextprime(p)
|
可以通过对N开根号求出后面的q(注意此处需要用sympy的sqrt,math库的sqrt无法求解这么大的数)
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import hashlib import sympy from Crypto.Util.number import * e = 0x10001 N=636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163 m1=90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239 m2=487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546 q=sympy.nextprime(sympy.sqrt(N)) p=sympy.prevprime(q) print(p*q==N) phi=(p-1)*(q-1) d=int(sympy.invert(e,phi)) c1=pow(m1,d,N) c2=pow(m2,d,N) from z3 import* f=Solver() F1,F2=Int('F1'),Int('F2') f.add(F1+F2==c1,pow(F1,3)+pow(F2,3)==c2) while f.check()==sat: m=f.model() nF1,nF2=m[F1],m[F2] f.add(Or(F1!=nF1,F2!=nF2)) flag1,flag2=long_to_bytes(int(str(nF1))),long_to_bytes(int(str(nF2))) flag=flag1+flag2 print(flag)
|
最终通过求解phi(N)((p-1)*(q-1))和e关于模phi(N)的逆元
通过公式 c=pow(m,d,N)就可以求解出对应的明文了
结果(因为F1和F2等价所以有两个值)
![image-20230702001150741](/images/loading.svg)