題目
Cross_Fire.py
from gmpy2 import *
from libnum import s2n,n2s
from Crypto.Util.number import *
from flag import plaintext
assert(len(plaintext)>128)
e=65537
m=s2n(plaintext)
p=getPrime(500)
q=getPrime(1024)
r=getPrime(1024)
hint1=p*q*r
hint2=next_prime(p)*next_prime(q)*next_prime(r)
n=next_prime(123*p+456)*next_prime(233*q+233)*next_prime(666*r+666)
c=pow(m,e,n)
print("hint1=",hint1)
print("hint2=",hint2)
print("e=",e)
print("n=",n)
print("c=",c)
'''
hint1= 66597706438052968602907975635364474124624609040691375744383573309100970537667852695911406578339583406993354597653539587007399024156000284162006381513057917653763467490913961403796256103799712489840324677890516295291754752667080587689619591977796148937147026181153407872286012339573004262967216008992456987530280248046317633785368985937352761743401538167742790063446090181640923337990535120783172231525752911772643973809736013911022053243030289179238536988831429875919863032051710061637295482848897179403927441453047333367742504111531477527219109139209305898423562329209375385774722090035022238350104808001927840789351874748994613148197348389169808276135120368108948370654768586592518609889834086412071206692748953099899446867217942417300125520378227882738726940028929
hint2= 66597706438052968602907975635364474124624609040691375744383573309100970537667852695911406578339583406993354597653539587007399024156000284162006381519250037838090700817357286993539595751890863552857025186501118668940000586180857161834771657275281213521087010590085823066429019242511957345355841205805490396285530197202608369351669705515187871274740384884445010749950651326231261308185878145343225072286358030343013074077614396504748731540529394175170653286604110001303387433196918194353309815286558369700754725062771941489664316582212235229725924291159030267475029526286194732206037792356401019048507530494720324382797923052122766854647054667572207470351698834488250064200327557388850421313632751275068766021705342276955127790709872384961830995521889674866200643581197
e= 65537
n= 1271143363426234578109032622706784368982452702551117975547220359092039459949589311614475250751670324493441017909825758822014002389769016887770094631267325830636300148439767061540517538240094507617502786636783685853116121519909167755693185341466272016646232460012649033718198945340871434729792726475237884312244749128647675044166254114409979208613136490968091271215324179363007030770031883104198634577994666369930225951242263540549447415742095183638116238138212512007206154136596565735565134655180583298422538746349678634986942613303728294063886412713958813109459261894779056221585991240656450995515329105180293668452080201635903397760758605883754955173299769359099672851020901544947845931039456152020654355740641530636597180573996251235682717406311406638139251493213898068501
c= 1216485134271178449567116916754420573073303455397620989326464150108908572336526711707238151485187836142308657852844139181641136164876989706372528330194558764108985905734554870749686706876362171680539349216110583849976294434959121174943229853669205013854742739444539161076289486434305028669545715151531610132849739705231210851708893517910447015945450432744842995436173783966889593804335503774508824344205419870078981016701436069437155486571657204182510954434683255699530711440688659074538879785922444601494725802905576491078834520957416860895991743319707987718280613091465577249499325647665822748760483739502978877174961037108839466736686647462799492964587695553596641935803152814769663732674949417986994233658218593205643014847168221928973615157533648368075119704854913178864
'''
0x01 連分數
連分數腳本
from Crypto.Util.number import *
from gmpy2 import *
N1= 66597706438052968602907975635364474124624609040691375744383573309100970537667852695911406578339583406993354597653539587007399024156000284162006381513057917653763467490913961403796256103799712489840324677890516295291754752667080587689619591977796148937147026181153407872286012339573004262967216008992456987530280248046317633785368985937352761743401538167742790063446090181640923337990535120783172231525752911772643973809736013911022053243030289179238536988831429875919863032051710061637295482848897179403927441453047333367742504111531477527219109139209305898423562329209375385774722090035022238350104808001927840789351874748994613148197348389169808276135120368108948370654768586592518609889834086412071206692748953099899446867217942417300125520378227882738726940028929
N2= 1271143363426234578109032622706784368982452702551117975547220359092039459949589311614475250751670324493441017909825758822014002389769016887770094631267325830636300148439767061540517538240094507617502786636783685853116121519909167755693185341466272016646232460012649033718198945340871434729792726475237884312244749128647675044166254114409979208613136490968091271215324179363007030770031883104198634577994666369930225951242263540549447415742095183638116238138212512007206154136596565735565134655180583298422538746349678634986942613303728294063886412713958813109459261894779056221585991240656450995515329105180293668452080201635903397760758605883754955173299769359099672851020901544947845931039456152020654355740641530636597180573996251235682717406311406638139251493213898068501
def continuedFra(x, y): #不斷生成連分數的項
cF = []
while y:
cF += [x // y]
x, y = y, x % y
return cF
def Simplify(ctnf): #化簡
numerator = 0
denominator = 1
for x in ctnf[::-1]: #注意這里是倒敘遍歷
numerator, denominator = denominator, x * denominator + numerator
return (numerator, denominator) #把連分數分成分子和算出來的分母
def getit(c):
cf=[]
for i in range(1,len(c)):
cf.append(Simplify(c[:i])) #各個階段的連分數的分子和分母
return cf #得到一串連分數
def wienerAttack(e, n):
cf=continuedFra(e,n)
for (Q2,Q1) in getit(cf):#遍歷得到的連分數,令分子分母分別是Q2,Q1
if Q1 == 0:
continue
if N1%Q1==0 and Q1!=1:#滿足這個條件就找到了
return Q1
print('not find!')
Q1=wienerAttack(N1,N2)
print(Q1)
hint1和hint2自然是我們的首要目標,但是對於一個大整數,尋找他的因子是比較難的,對於這一步,是使用連分數的方法去嘗試尋找因子,但是這種方法不是百分百成功的。
什么是連分數,舉個例子,因為我們需要尋找素數因子,所以模仿題目三個素數相乘。
可以發現a的因子3出現在了式子中。這一題也是可以解出p的值的,但是不是所有整數都可以用連分數找因子。
本題構造一個,其中包含一個
,可以試着解出p,因為p位數較小,所以可能性比較大,若解出了其他因子也無妨。
0x02 相鄰素數之差
連分數法解出了因子p,剩下的問題就是怎么在二元一次方程中找到q和r。
可以把next_prime(x)函數看作是加上一個未知數。
雖然說相鄰素數之差可以無限大,但是題目中可以說是不可能的,猜測他們的差值,遍歷所有可能的差值來計算出q和r。
遍歷差值
from sympy import *
q = Symbol('q')
r = Symbol('r')
qr = 24000465830725710567609789107532324217407562259754653134149621603287774548503009977306790950765445986759457303910590756566445763189685864660421027894624160496364130162710203056019260859349197460287247433237333855820008311336990774902044072459096643794460636549390819914523204123744097150936438700304426418945328341075502713761684579112067780970129462407486292351679441221444463557410246953331098106055732155261630435421138374418050504535474800628754964367103623724936338041432343848497819682915988508211563927368529558866912220856126132024687748646133065560766894641603193094511181987021442275364527221213343560893411
qr1 = 24000465830725710567609789107532324217407562259754653134149621603287774548503009977306790950765445986759457303910590756566445763189685864660421027894624160496364130162710203056019260859349197460287247433237333855820008311336990774902044072459096643794460636549390819914523204123744097150936438700304426419195181206357035254463948831711777035126077563377919684721062749439252724456974588213705559491260601777470792467850627398598289093915869715222818079606170004475810187367332322557611964471968738992807153326972570559359950761752890888829934863609591544119615229826879764045397320279541476417371138268264031865992001
for i in range(1,2000):
if i %2 != 0:
continue
for j in range(1,5000):
if j %2 != 0:
continue
if solve([q * r -qr,(q + i) * (r + j) - qr1],[q,r]) != []:
print(solve([q * r -qr,(q + i) * (r + j) - qr1],[q,r]))
if j % 100 == 0:
print("i=",i," j=",j)
拿到q和r之后就正常解密就行。
0x03 解密
解密
from Crypto.Util.number import *
from gmpy2 import *
p = 2774850576141472759750346775261325452644460973401850287932931620311032092916729637191098025961817446165726519739952039305052387235887276749354299156939
q = 139641381249675277096030502006635552984850220001722457942384913797258117311623650034390706920802632432660743916051339655260592072917158303514226459514087900506977001396105773357335107835122085763967512170594553044135889886657882543096229377186458172209133529253087532281788796666680318073771593970758461389983
r = 171872160071329295838941449584454449746048702878711264692237254894810882484059864060426363550429058945413590178776495557183107631846765398786315563075169313438191268458878134349212862474473833156356093348510192513378625214184466322078940263408962588767078154640710788914808919327606595270722276798324035513917
e= 65537
c= 1216485134271178449567116916754420573073303455397620989326464150108908572336526711707238151485187836142308657852844139181641136164876989706372528330194558764108985905734554870749686706876362171680539349216110583849976294434959121174943229853669205013854742739444539161076289486434305028669545715151531610132849739705231210851708893517910447015945450432744842995436173783966889593804335503774508824344205419870078981016701436069437155486571657204182510954434683255699530711440688659074538879785922444601494725802905576491078834520957416860895991743319707987718280613091465577249499325647665822748760483739502978877174961037108839466736686647462799492964587695553596641935803152814769663732674949417986994233658218593205643014847168221928973615157533648368075119704854913178864
n=next_prime(123*p+456)*next_prime(233*q+233)*next_prime(666*r+666)
p = next_prime(123*p+456)
q = next_prime(233*q+233)
r = next_prime(666*r+666)
phi = (p-1)*(q-1)*(r-1)
d = invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))