2021年全国大学生信息安全竞赛安徽省赛-网络攻防赛道-部分wp-Crypto-Cross_Fire

题目

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自然是我们的首要目标,但是对于一个大整数,寻找他的因子是比较难的,对于这一步,是使用连分数的方法去尝试寻找因子,但是这种方法不是百分百成功的。

        什么是连分数,举个例子,因为我们需要寻找素数因子,所以模仿题目三个素数相乘。
        image

        可以发现a的因子3出现在了式子中。这一题也是可以解出p的值的,但是不是所有整数都可以用连分数找因子。

        本题构造一个image,其中包含一个image,可以试着解出p,因为p位数较小,所以可能性比较大,若解出了其他因子也无妨。

0x02 相邻素数之差

        连分数法解出了因子p,剩下的问题就是怎么在二元一次方程中找到q和r。
        可以把next_prime(x)函数看作是加上一个未知数。
        image
        虽然说相邻素数之差可以无限大,但是题目中可以说是不可能的,猜测他们的差值,遍历所有可能的差值来计算出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))
posted @ 2021-10-30 10:22  Sentry_InkCity  阅读(678)  评论(2编辑  收藏  举报