题目描述:
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=636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163
m1=90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
m2=487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546
题目分析:
对代码进行分析可得大致加密过程为:
- 首先给了字符串明文flag和secret,然后对flag对半切得到flag1和flag2
- 随机生成一个1024位(2进制)的素数,并将secret(字符串)类型转化为整数类型,然后将这两个结果相乘得到secret_num
拓展:
bytes_to_long(x) —> 字节转整数 (会将字节x转化为它的ascii码)
long_to_bytes(x) —> 整数转字节
- 取secret_num的下一个素数作为p,取p的下一个素数作为q,得到N=p*q
必备知识:
sympy.prevprime(x)是求大于x最近的质数
sympy.nextprime(x)是求小于x最近的质数
- 将flag1和flag2通过bytes_to_long转化为整数得到F1和F2
- 将F1,F2设计成方程组得到c1,c2,进一步加密得到m1,m2
- 最后给出运行结果得到 N,m1,m2
decrypt(解密)
- 题中给出了N,通过以上分析可以得知p,q是两个相邻的素数,所以对N进行开方运算(iroot(N,2))后可以得到一个值x,并且pq
- 通过sympy.prevprime(x),sympy.nextprime(x) 函数可以得到p,q,从而可以求得d
- 然后进行RSA解密得出c1和c2
c1 = pow(m1,d,N)
c2 = pow(m2,d,N)
- 至此,我们得到一个方程组:
c1=F1+F2
c2=F13+F23
- 利用sympy库进行方程组求解:
from sympy import *
F1 = Symbol('F1')
F2 = Symbol('F2')
F1,F2 = solve([F1+F2-c1,(F1)**3+(F2)**3-c2])
得到:
{F1: 1141553212031156130619789508463772513350070909, F2: 1590956290598033029862556611630426044507841845},
{F1: 1590956290598033029862556611630426044507841845, F2: 1141553212031156130619789508463772513350070909}
- 得到两组解,但仔细看只是调换的位置而已,两组都试一下,便可得到最终flag
- 完整代码:
N=636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163
m1=90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
m2=487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546
e = 65537
import gmpy2
import libnum
import sympy.crypto.crypto
x = gmpy2.iroot(N,2)[0]
p = sympy.nextprime(x)
q = N//p
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
# m1 = pow(c1, e, N)
# m2 = pow(c2, e, N)
c1 = pow(m1,d,N)
c2 = pow(m2,d,N)
from sympy import *
F1 = Symbol('F1')
F2 = Symbol('F2')
print(solve([F1+F2-c1,(F1)**3+(F2)**3-c2]),F1,F2)
F1,F2 = solve([F1+F2-c1,(F1)**3+(F2)**3-c2])
F2 = 1141553212031156130619789508463772513350070909
F1 = 1590956290598033029862556611630426044507841845
print(libnum.n2s(int(F1))+libnum.n2s(int(F2)))
- 最后得到flag{f709e0e2cfe7e530ca8972959a1033b2}
收获与体会:
- 了解了bytes_to_long(x) 与 long_to_bytes(x) 相关知识
- 代码中有一步有点一知半解
m1 = pow(c1, e, N)
m2 = pow(c2, e, N)
---->(这里有点迷)
c1 = pow(m1,d,N)
c2 = pow(m2,d,N)