RSA常见题型二(e与φ(n)不互素)

e与φ(n)不互素

1.e与(p-1)或(q-1)互素,则将(p-1)或(q-1)视为φ(n)

例题:

题目:

from Crypto.Util.number import *
from secret import flag
m=bytes_to_long(flag)
p=getPrime(512)
q=getPrime(512)
print('p=',p)
print('q=',q)
n=p*q
e=65537
c=pow(m,e,n)
print('c=',c)
#p= 12408795636519868275579286477747181009018504169827579387457997229774738126230652970860811085539129972962189443268046963335610845404214331426857155412988073
#q= 12190036856294802286447270376342375357864587534233715766210874702670724440751066267168907565322961270655972226761426182258587581206888580394726683112820379
#c= 68960610962019321576894097705679955071402844421318149418040507036722717269530195000135979777852568744281930839319120003106023209276898286482202725287026853925179071583797231099755287410760748104635674307266042492611618076506037004587354018148812584502385622631122387857218023049204722123597067641896169655595

首先,用常规方法做,出现错误

2025-07-24 152538

检查,发现e与φ(n)不互素,但e与(p-1)互素

import math
e=65537
p= 12408795636519868275579286477747181009018504169827579387457997229774738126230652970860811085539129972962189443268046963335610845404214331426857155412988073
q= 12190036856294802286447270376342375357864587534233715766210874702670724440751066267168907565322961270655972226761426182258587581206888580394726683112820379
phi_n=(p-1)*(q-1)
print(math.gcd(e,phi_n))  #65537
print(math.gcd(e,p-1))    #1
print(math.gcd(e,q-1))    #65537

则将(p-1)视为φ(n),并且将p作为模数

解密代码如下:

import gmpy2
from Crypto.Util.number import long_to_bytes
e=65537
p= 12408795636519868275579286477747181009018504169827579387457997229774738126230652970860811085539129972962189443268046963335610845404214331426857155412988073
q= 12190036856294802286447270376342375357864587534233715766210874702670724440751066267168907565322961270655972226761426182258587581206888580394726683112820379
c= 68960610962019321576894097705679955071402844421318149418040507036722717269530195000135979777852568744281930839319120003106023209276898286482202725287026853925179071583797231099755287410760748104635674307266042492611618076506037004587354018148812584502385622631122387857218023049204722123597067641896169655595
phi_n=p-1
d=gmpy2.invert(e,phi_n)
m=pow(c,d,p)
print(long_to_bytes(m))

例题2:

题目:

n = 3454083680130687060405946528826790951695785465926614724373
e = 3
c = 1347530713288996422676156069761604101177635382955634367208

首先对n进行分解(yafu分解),结果如下:
2025-07-24 2

检查,发现:

import math
p = 17100682436035561357
q = 11761833764528579549
r = 17172929050033177661
e=3
print(math.gcd(e,p-1))  #3
print(math.gcd(e,q-1))  #1
print(math.gcd(e,r-1))  #1

将(q-1)*(r-1)视为φ(n),q * r 视为模数

解密代码如下:

import gmpy2
from Crypto.Util.number import long_to_bytes
p = 17100682436035561357
q = 11761833764528579549
r = 17172929050033177661
e=3
c = 1347530713288996422676156069761604101177635382955634367208
n = q * r
phi_n = (q-1)*(r-1)
d =gmpy2.invert(e,phi_n)
m = pow(c,d,n)
print(long_to_bytes(m)) #b'CMISCCTF{3_RSA}'
2.e与(p-1)和(q-1)均不互素,则通过有限域开方解密

例题1:

题目:

from Crypto.Util.number import bytes_to_long
from secret import flag
e = 0x14
p = 733089589724903586073820965792963746076789390539824437962807679954808310072656817423828613938510684864567664345751164944269489647964227519307980688068059059377123391499328155025962198363435968318689113750910755244276996554328840879221120846257832190569086861774466785101694608744384540722995426474322431441
q = 771182695213910447650732428220054698293987458796864628535794956332865106301119308051373568460701145677164052375651484670636989109023957702790185901445649197004100341656188532246838220216919835415376078688888076677350412398198442910825884505318258393640994788407100699355386681624118606588957344077387058721
n = p*q
m = bytes_to_long(flag)
c = pow(m,e,n)
print(c)
#406314720119562590605554101860453913891646775958515375190169046313074168423687276987576196367702523895650602252851191274766072774312855212771035294337840170341052016067631007495713764510925931612800335613551752201920460877432379214684677593342046715833439574705829048358675771542989832566579493199671622475225225451781214904100440695928239014046619329247750637911015313431804069312072581674845078940868349474663382442540424342613429896445329365750444298236684237769335405534090013035238333534521759502103604033307768304224154383880727399879024077733935062478113298538634071453067782212909271392163928445051705642

检查,发现e与φ(n),p-1,q-1都不互素

import math
e = 0x14
p = 733089589724903586073820965792963746076789390539824437962807679954808310072656817423828613938510684864567664345751164944269489647964227519307980688068059059377123391499328155025962198363435968318689113750910755244276996554328840879221120846257832190569086861774466785101694608744384540722995426474322431441
q = 771182695213910447650732428220054698293987458796864628535794956332865106301119308051373568460701145677164052375651484670636989109023957702790185901445649197004100341656188532246838220216919835415376078688888076677350412398198442910825884505318258393640994788407100699355386681624118606588957344077387058721
phi_n=(p-1)*(q-1)
print(math.gcd(e,phi_n)) #20
print(math.gcd(e,p-1))   #20
print(math.gcd(e,q-1))   #20

有限域开方原理:
有限域

根据上述推理的结论,首先判断c和n的大小,发现从c<n,则直接开方,但是开出来是乱码

import gmpy2
from Crypto.Util.number import long_to_bytes
p = 733089589724903586073820965792963746076789390539824437962807679954808310072656817423828613938510684864567664345751164944269489647964227519307980688068059059377123391499328155025962198363435968318689113750910755244276996554328840879221120846257832190569086861774466785101694608744384540722995426474322431441
q = 771182695213910447650732428220054698293987458796864628535794956332865106301119308051373568460701145677164052375651484670636989109023957702790185901445649197004100341656188532246838220216919835415376078688888076677350412398198442910825884505318258393640994788407100699355386681624118606588957344077387058721
c = 406314720119562590605554101860453913891646775958515375190169046313074168423687276987576196367702523895650602252851191274766072774312855212771035294337840170341052016067631007495713764510925931612800335613551752201920460877432379214684677593342046715833439574705829048358675771542989832566579493199671622475225225451781214904100440695928239014046619329247750637911015313431804069312072581674845078940868349474663382442540424342613429896445329365750444298236684237769335405534090013035238333534521759502103604033307768304224154383880727399879024077733935062478113298538634071453067782212909271392163928445051705642
n = p*q
print(c>n)                      #False
res=gmpy2.iroot(c,20)
print(long_to_bytes(res[0]))    #b'0\t\x1fn\xc5+\xbc\xa9:\x03\xb3A\xf3'

那就直接用第二种方法:有限域开方

首先求方程f=x^e-c在模p和模q下的根

R.<x> = Zmod(p)[]#R.<x> = Zmop(q)[]
f = x ^ e - c
f = f.monic()
res1 = f.roots()

这段代码是在数学软件sage中运行的

R. = Zmod(p)[] 这一句,R 表示多项式环的名称, 表示所定义的环中的变量名是x,而 Zmod(p)[] 表示在模p的意义下定义了一个多项式。其中每个多项式的系数都是p的倍数,以确保在模p的意义下进行运算时不会出现浮点运算精度的问题

接下来,代码定义了一个多项式 f = x^e - c。再将这个多项式调整为monic的形式(monic多项式即次数最高项的系数为1),并被保存在变量f中,以便计算方程的根

接下来,代码调用了多项式 f 的roots() 方法,得到方程的一个根的列表。最终生成的变量res1是多项式f在模p意义下的所有根组成的列表。如果方程没有解,则res1变量将为空列表

根列表

根列表的每个元素是一个二元组,第一个元素是方程的根,第二代元素表示根的重数,即该解在方程中出现的次数

接下来使用中国剩余定理求解

中国剩余定理:

中国剩余定理

中国剩余定理是一个关于一元线性同余方程组的定理,说明了一元线性同余方程组有解的准则以及求解方法。

前提:整数m1,m2,m3…mn两两互素。

对于任意的整数x,满足以上方程组,则都存在整数解x

若X,Y都满足该方程组,则必有
2025-07-24 4
其中
2025-07-24 5

由于证明过程有点复杂,难以理解,我就通过一个简单的例子来理解,线性同余方程组如下:

屏幕截图 2025-07-24 6

大体思路:找三个数,分别为a,b,c,其中a模3等于1,模5等于0,模7等于0,b模3等于0,模5等于1,模7等于0,c模3等于0,模5等于0,模7等于1

a模3等于1,模5等于0,模7等于0:

a要满足模5等于0,模7等于0,则a是5和7的最小公倍数的倍数,即35的倍数。又要满足模3等于1,推算出a=70

同理可得b,c

那么,x = a + b + c

具体代码如下:

from Crypto.Util.number import  *
import libnum

p = 733089589724903586073820965792963746076789390539824437962807679954808310072656817423828613938510684864567664345751164944269489647964227519307980688068059059377123391499328155025962198363435968318689113750910755244276996554328840879221120846257832190569086861774466785101694608744384540722995426474322431441
q = 771182695213910447650732428220054698293987458796864628535794956332865106301119308051373568460701145677164052375651484670636989109023957702790185901445649197004100341656188532246838220216919835415376078688888076677350412398198442910825884505318258393640994788407100699355386681624118606588957344077387058721
n = 9057141637995599750120273501711128117576789048411357158233050845658505488383724832915968443730006384810721595601723748471745315354759415044859624198755098491311647992728384572103262800310263916249536898582100747311978019829291619921741682336800665277699122504431456051606407509905004993708771825443764723285750825546500765451509998514747599779552241055519485714649825416851221219747115910385536482995890893190128149999622905611239433481756073333147782531765685320972075370276543786386451560493093416152466142374684450770169257924330366774896526508005296520372463932722237001341584625279676089901419404816917142209281664709940400762785892142918132066900664643155176180059403739
c = 406314720119562590605554101860453913891646775958515375190169046313074168423687276987576196367702523895650602252851191274766072774312855212771035294337840170341052016067631007495713764510925931612800335613551752201920460877432379214684677593342046715833439574705829048358675771542989832566579493199671622475225225451781214904100440695928239014046619329247750637911015313431804069312072581674845078940868349474663382442540424342613429896445329365750444298236684237769335405534090013035238333534521759502103604033307768304224154383880727399879024077733935062478113298538634071453067782212909271392163928445051705642
e= 20
res1= [(733089589724903586073820965792963746076789390539824437962807679954808310072656817423828613938510684864567664345751164944269489647964227519307980688068059059377123391499328155021524914773359906357153671313308407478602554319510265005085762860382683102940576377254668898119652133942180899304170329371707150164, 1), (678923693209704969852381465896650019425870260030383443168808423368601278880685781654734919678958092826800695579102973572447355792679848485826507692704568923813419881117766044423608229711484763917744685055881596752291255735808048270822124796786471676188662798449644642235738223466855946913879538299578053411, 1), (660147311087779881169338548239431864756054612093222666998714749603875812596923472248793683967669014397990139199125982652383529516284367882454604795633984744310817735291839918294987220579419849435923577095190063747058566440604560174772236817980884692508913814109640678513633481822665261866470516425285518285, 1), (656681791452498481654878002485070757012861926668381629152705461263764608739765714942200770232734120738697878503189820956143274111419030898383980731253182784661086554234440727684677249747860741931943770929571071514986737487620545162638141249825931408013949005076717924474881049785216136013509251488319927117, 1), (561634200460522548441571592444405305656486299630777500288946777401428565675621685143645766539546494757183424411676233243328896459121008394512864385381461601416842364770773986015469061716463481506742063309940039220834724151367845375195245551456554735236102965922407472562800115189890526203678874326289793386, 1), (523855729860851889306276946831707325654966799659419971520448260469324992736982246556398347232993411720682146837875080052611076416766800095923505800210207882786055877101711481659849019405604591067848093320332336464705973049736439281995689523942160283871387832933740244138033780213828909573276367363492479416, 1), (452900182350324645394395847267638113925741103910755278893324277011525974119646860179890955142636700494806732282459985420380030145373473199426467982810188731584443697329277404941404099390850352429776960314100205943189386609329123884794268027928641499784873014598307047385649837271871153730516499924907326391, 1), (416370840270302176660974325650517943145426999919261282193286142404178655729051589183139277588858670001090144796272169390365633208042166264602215868369443740484308138194802614266542495845026116458981772823239562965336426568684608791041112836390368657079922805426770894892558562813602601339340032501607476909, 1), (415121711750653986259101201654940133924221603939397750124825760079422401181007421592643535836083617458305454708658832229662210103019264900837109397638935012953657209660214900590221340670067523952418432762094850952735077742516293665730069986289396136048668366129437705942925977098013178518939090064725293698, 1), (374350165605081425148746685793120637325474206554845188409530082476947889392734021316375944344139500560536749012063348621966245700071777272257861879442907414106249944743486841972083642001920163764631575788319343002998139757149039708713099627493777332364552928705440787113844863245759659045732547084424923730, 1), (358739424119822160925074279999843108751315183984979249553277597477860420679922796107452669594371184304030915333687816322303243947892450247050118808625151645270873446755841313053878556361515804554057537962591412241278856797179801170508021218764054858204533933069025997987849745498624881677262879389897507711, 1), (317967877974249599814719764138023612152567786600426687837981919875385908891649395831185078102427067406262209637092332714607279544944962618470871290429124046423466181839113254435740857693368444366270680988815904291541918811812547213491050859968436054520418495645029079158768631646371362204056336409597137743, 1), (316718749454601409412846640142445802931362390620563155769521537550629654343605228240689336349652014863477519549478995553903856439922061254705764819698615318892815253304525540759419702518409851859707340927671192278940569985644232088180008009867463533489164056347695890209136045930781939383655393972714954532, 1), (280189407374578940679425118525325632151048286629069159069483402943282335953009957243937658795873984369760932063291179523889459502590754319881512705257870327792679694170050750084558098972585615888912153436810549301087609944999716994426852818329190690784213847176159737716044771472513386992478926549415105050, 1), (209233859864051696767544018961256420421822590880404466442359419485483317335674570867430266705517273143885517507876084891658413231197427423384474887857851176591067514397616673366113178957831377250841020430578418779571023504592401597225431322315671906697699028840726540963660828530555631149719059110829952025, 1), (171455389264381037632249373348558440420303090909046937673860902553379744397035132280182847398964190107384239934074931700940593188843219124795116302686597457960281026728554169010493136646972486811947050440970716023442272402960995504025875294801277455332983895852059312538894493554494014519316552148032638055, 1), (76407798272405104418942963307892989063927463871442808810102218691043701332891102481627843705776564125869785842561343988126215536545196620923999956814876274716036837264887427341284948615575226386745342821339683729290259066708295716582979596431900782555137856697748860626813558959168404709486174986002504324, 1), (72942278637123704904482417553531881320734778446601770964092930350932497475733345175034929970841670466577525146625182291885960131679859636853375892434074315066305656207488236730974977784016118882765536655720691497218430113724280704448884028276947498060173047664826106588061126921719278856524910049036913156, 1), (54165896515198616221439499896313726650919130509440994793999256586207031191971035769093694259552592037766968766648191371822133855284379033481472995363490135563703510381562110602353968651951204400944428695029158491985740818520792608398996049471360514380424063324822142865956385277528593809115888174744378030, 1), (4437283590076061961535442437602347765674442234818575874135357985875149087628510484519797886982042474802203641418825097102615281277, 1)]
res2= [(771182695213910447650732428220054698293987458796864628535794956332865106301119308051373568460701145677164052375651484670636989109023957702790185901445649197004100341656188532242400936626843773453840636251285728911675970163379867036690526519443109306012484303887302812373344206821914965170132246974771777444, 1), (766556454188661342717183441830753958949866417494716064331308873001400640185512932266682617111675304940672393843056881975135838366629757426494074139282338667675175892353840088889909195938963702112766349904198019372558645141384798583534383188883052267525748815134207587721641571601904662560056137622206973489, 1), (697252901173481151775023987079186148934671702095573239439077382532564148810196647295908000048808838516420504907242412420648310319468654564849006791509953203253591756022067984445917819993348421480837383431739473210443093160532003684668638512409524578887612424272056500338100724912084684072451333028872106867, 1), (637570615943233551403071638054753581415867520631437658239907745441121975126808316940174715476757666870531167942851357415707186407189108694841070152707092245309731475509435021166725640089960139181871460785130772780846084823629102758039859600829870217520667468256249544673326609044266687450424519008597139038, 1), (632327011426499994189315859401811158465010667761983995201046936822397685624551714172153350143852663041545272586491513748551456122474881151730273573849696707727190136249011496534362800230143294818909726182851035741169036440948865157971659975327810387018738693032165869052686855576696780303333160382173118510, 1), (603167942216453034450263940413887436639768290870012743059006350279961914111784943446402628202860617054930140073926171776018499373620898476085657301360306887162235526834606378738074341266663645930616670338128013164422994099750629106515540742416974080150559276654019646352903381932805758744985229930025215589, 1), (530466680163017973833308694998245966701824340964042532641356089137879243186221081260746979341797675072378875885003058544820764758046575857925699945279145064801793820479054735901259358468262299180565694104881447986591164582548172740211166270336596928161447369253455709413986912995034928572096835678138857265, 1), (465540790416036816247600567320870976232163306630453288403325643427712780000576148136992329436841499597503643564252159872723910561052802444806966727618888569275392200705998247985267055114981110557102594418390662751642665628146458339378829747379733648664063153493767191146530568857443383384153565928824587631, 1), (416074710242252176401044812192140737030784340427479537135890013577916016785682458613448218282243236911584933444225849145353809933396731357693587977285142052644526842758534194394543388181747428573306033684592492190246496510265285685848535401569621598453391802767037373579958843978087833160938909090562342099, 1), (394136899723687893136044300058080845383423389432958570785292421247573616646066598716388388801380799317671805332945423860473016951589636840148122537670603031835993896874831423637875155136425033395934564235988401408318773868625275203793169278596739058672957150515186335729596174779705646162358930520576725303, 1), (377045795490222554514688128161973852910564069363906057750502535085291489655052709334985179659320346359492247042706060810163972157434320862642063363775046165168106444781357108608963065080494802019441514452899675269031638529573167707032715226721519334968037637891914363625790506844412960426598413556810333418, 1), (355107984971658271249687616027913961263203118369385091399904942754949089515436849437925350178457908765579118931425635525283179175627226345096597924160507144359573498897654337852294832035172406842070045004295584487103915887933157224977349103748636795187602985640063325775427837646030773428018434986824716622, 1), (305641904797873631403131860899183722061824152166411340132469312905152326300543159914381239023859646079660408811399324797913078547971155257983219173826760627728708140950190284261571165101938724858273484270497413925707746770051984571447054757938524744976931634913333508208856112766675223204803778148562471090, 1), (240716015050892473817423733221808731592163117832822095894438867194985863114898226790626589118903470604785176490648426125816224350977381844864485956166504132202306521177133796345578861748657536234810384584006628690759247815650270170614718234981661465479547419153644989941399768629083678016860508399248201456, 1), (168014752997457413200468487806167261654219167926851885476788606052903192189334364604970940257840528622233912301725312894618489735403059226704528600085342309841864814821582153508763878950256189484759408350760063512927418298447813804310343762901284313490435511753081053002483299691312847843972114147361843132, 1), (138855683787410453461416568818243539828976791034880633334748019510467420676567593879220218316848482635618779789159970922085532986549076551059912327595952489276910205407177035712475419986776540596466352506037040936181375957249577752854224529990448006622256095374934830302699826047421826285624183695213940211, 1), (133612079270676896247660790165301116878119938165426970295887210891743131174310991111198852983943478806632884432800127254929802701834849007949115748738556951694368866146753511080112580126959696233504617903757303896504327574569340152786024904488388176120327320150851154682060072579851919138532825068789919683, 1), (73929794040429295875708441140868549359315756701291389096717573800300957490922660755465568411892307160743547468409072249988678789555303137941179109935695993750508585634120547800920400223571413934538695257148603466907319237666439226157245992908733814753382364135044199017285956712033922516506011048514951854, 1), (4626241025249104933548986389300739344121041302148564204486083331464466115606375784690951349025840736491658532594602695501150742394200276296111762163310529328924449302348443356929024277956133302609728784690057304791767256813644327291501316435206126115245973272893111633745110022213944028901206455180085232, 1), (4437283590076061961535442437602347765674442234818575874135357985875149087628510484519797886982042474802203641418825097102615281277, 1)]
for i in res1:
    for j in res2:
        # 中国剩余定理
        m =libnum.solve_crt([int(i[0]),int(j[0])],[p,q])
        #c3=libnum.solve_crt([c1,c2], [q1,q2])
        #solve_crt()函数用于找到满足同余方程组的最小整数解x,第一个参数是余数列表,第二个参数是模数列表,两个列表的长度要相同,第二个参数中的模数要两两互素
        flag = long_to_bytes(m)
        if flag.startswith(b'flag'):
            print(flag)

例题2:

题目:

c = 2485360255306619684345131431867350432205477625621366642887752720125176463993839766742234027524
n = 0x2CAA9C09DC1061E507E5B7F39DDE3455FCFE127A2C69B621C83FD9D3D3EAA3AAC42147CD7188C53
e = 3

首先,在线网站分解n,结果如下:

屏幕截图 2025-07-24 8

检查,发现gcd(e,q-1)=1

import math
e = 3
p = 26440615366395242196516853423447
q = 27038194053540661979045656526063
r = 32581479300404876772405716877547
print(math.gcd(e,p-1))  #3
print(math.gcd(e,q-1))  #1
print(math.gcd(e,r-1))  #3

则将q-1视为φ(n),模数变成q,具体代码如下:

import gmpy2
from Crypto.Util.number import long_to_bytes
e = 3
q = 27038194053540661979045656526063
c = 2485360255306619684345131431867350432205477625621366642887752720125176463993839766742234027524
d = gmpy2.invert(e,q-1)
m = pow(c,d,q)
print(long_to_bytes(m)) #b'\xf7\x99\xdc6L"\xb3YN\xee\x17\x17l'

发现,无法得到正确的flag,和第一个例题相比,第一个例题中,p明显比flag大,所以单独用p可以算出来,但是这道题q比较小,所以算不出。

那就尝试有限域开方求解,代码如下:

from Crypto.Util.number import long_to_bytes
import libnum
e = 3
p = 26440615366395242196516853423447
q = 27038194053540661979045656526063
r = 32581479300404876772405716877547
c = 2485360255306619684345131431867350432205477625621366642887752720125176463993839766742234027524
n = 23292710978670380403641273270002884747060006568046290011918413375473934024039715180540887338067
'''
在sage中执行如下程序,得到res1,res2,res3
R.<x> = Zmod(p)[]
f = x ^ e -c
f = f.monic()
res1 = f.roots()

R.<x> = Zmod(q)[]
f = x ^ e -c
f = f.monic()
res2 = f.roots()

R.<x> = Zmod(r)[]
f = x ^ e -c
f = f.monic()
res3 = f.roots()
'''
res1 = [(13374868592866626517389128266735, 1), (7379361747422713811654086477766, 1),
        (5686385026105901867473638678946, 1)]
res2 = [(19616973567618515464515107624812, 1)]
res3 = [(13404203109409336045283549715377, 1), (13028011585706956936052628027629, 1),
        (6149264605288583791069539134541, 1)]
for i in res1:
    for j in res2:
        for k in res3:
            m = libnum.solve_crt([(i[0]),(j[0]),(k[0])],[p,q,r])
            flag =long_to_bytes(m)
            if flag.__contains__(b'ctf'):
 #另一种写法:if b'ctf' in flag:
                print(flag)

例题3:

题目:

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

flag = b'xxx'
def Mypow(b, e, mod):
    a = 1
    while e:
        e >>= 1
        b = (b*b)%mod
        if e&1:
            a = (a*b)%mod
    return a

def Genp(bit_length):
    coeff = 2 ** 5 * 3 * 7
    while True:
        tmp_prime = getRandomNBitInteger(bit_length - 10)
        p = coeff * tmp_prime + 1
        if is_prime(p):
            break
    return p

def Genkeys(bit_length):
    p,q = Genp(bit_length),Genp(bit_length)
    n = p * q
    hint = (2 * p + 7 * q) % n
    return n, hint

if __name__ == '__main__':
    e = next_prime(666)
    n, hint = Genkeys(512)
    m = bytes_to_long(os.urandom(30) + flag)
    ct = Mypow(m,e,n)
    print(f'n = {n}')
    print(f'hint = {hint}')
    print(f'ct = {ct}')

'''
n = 36443283250594259606482132779262570582448178589602577809591307671554949253094255209079689901493052116793388954529442162972106210862341856282788030374324677114528044629385805693771773377070021111949953333360526159026822968061585876873187059674130307295006486032106471182393880915860569773206853864515489855553
hint = 57792516722001523643789088224096258172899052039145876393373730235406451592173971020702024058282699663364267742428240581839287357212741266617791207580236457
ct = 24482128269957355675512496312977308128712253968496848873519792376434347925427116612997489113223781321628516365811583310346553402215907938918891908853234881284620764982626375301219763593402089309909155204943747718536894186749932544428588048770663458669109073657836937287831725958017345747881678942488157429000
'''

特别注意一下题目中这段代码:

def Mypow(b, e, mod):
    a = 1
    while e:
        e >>= 1
        b = (b*b)%mod
        if e&1:
            a = (a*b)%mod
    return a

这段代码是一个快速幂取模的运算

原理:(通过一个例子来说明)

首先要知道取模的一些性质:

  • a % p = a % p % p
  • (a * b) % p = (a % p * b % p) % p
  • a ^ b % p =(a % p) ^ b % p

假设计算a^6 ,6的二进制为110

屏幕截图 2025-07-24 9

所以题目中的Mypow函数返回的值就是pow(m,e-1,n)

继续分析题目,可知n=p*q , hint = ( 2 * p +7 * q) % n,又因为 ( 2 * p +7 * q)一定小于n,所以hint = 2 * p +7 * q,因此,hint * p = 2 * p ^ 2 + 7 * n

求p,代码如下:

n = 36443283250594259606482132779262570582448178589602577809591307671554949253094255209079689901493052116793388954529442162972106210862341856282788030374324677114528044629385805693771773377070021111949953333360526159026822968061585876873187059674130307295006486032106471182393880915860569773206853864515489855553
hint = 57792516722001523643789088224096258172899052039145876393373730235406451592173971020702024058282699663364267742428240581839287357212741266617791207580236457
PR.<p> = PolynomialRing(Zmod())
f = 2 * p ^ 2 + 7 * n - hint * p
#print(f.roots())得到p
p = 5437194409937079365796361293969364604939627149039784073055530959237847229851327425147129937145179737622218931435682823431052499320577471182347267982471329
q = n // p

由题目,可知真正 的e = 672 = 2 ^ 5 * 3 *7,可以知道φ(n)与e,(p-1),(q-1)都不互素,所以直接有限域开方,代码如下:

import gmpy2
from Crypto.Util.number import *
import libnum
n = 36443283250594259606482132779262570582448178589602577809591307671554949253094255209079689901493052116793388954529442162972106210862341856282788030374324677114528044629385805693771773377070021111949953333360526159026822968061585876873187059674130307295006486032106471182393880915860569773206853864515489855553
hint = 57792516722001523643789088224096258172899052039145876393373730235406451592173971020702024058282699663364267742428240581839287357212741266617791207580236457
c = 24482128269957355675512496312977308128712253968496848873519792376434347925427116612997489113223781321628516365811583310346553402215907938918891908853234881284620764982626375301219763593402089309909155204943747718536894186749932544428588048770663458669109073657836937287831725958017345747881678942488157429000
e = 672
p = 5437194409937079365796361293969364604939627149039784073055530959237847229851327425147129937145179737622218931435682823431052499320577471182347267982471329
q = n // p

R.<x> = Zmod(p)[]
f = x ^ e - c
f = f.monic()
res1 = f.roots()

R.<x> = Zmod(q)[]
f = x ^ e - c
f = f.monic()
res2 = f.roots()

print('res1 =',res1)
print('res2 =',res2)

k = 0
for i in res1:
    for j in res2:
        m = libnum.solve_crt([int(i[0]),int(j[0])],[p,q])
        m = long_to_bytes(int(m))
3.补充:e与(p-1),(q-1)都不互素时的常规解法:

令t = gcd(e,phi)

e = e1 * t , e1 = e / t

c ≡ m ^ e mod n 即c ≡ (m ^ t) ^ e1 mod n

求出e1对应的d ,解出m ^ t ≡ c ^ d mod n

在m ^ t 小于n的情况下,直接开根即可获得m

例题:
import gmpy2
import libnum
import random
import uuid

flag = "flag{" + str(uuid.uuid4()) + "}"
print(flag)
m = libnum.s2n(flag)

while 1:
    e = random.randint(100, 1000)
    p = libnum.generate_prime(1024)
    q = libnum.generate_prime(1024)
    phi_n = (p - 1) * (q - 1)
    t = gmpy2.gcd(e, phi_n)
    if t == e:
        continue
    t1 = e // t
    if gmpy2.invert(t1, phi_n) and t > 1:
        break
n = p * q
c = pow(m, e, n)
print("p=", p)
print("q=", q)
print("e=", e)
print("c=", c)
'''
p = 171854505164939390402295426493389586289972154851849140728417624619463988154808053805729538974688869671559032639921300088271234681410193379381085714252211392886408792711387524667824537369266846649573070209815436507363007636943912350208275895292853801665488228125846058987049326903498661007035974420392738723323
q = 145951936627745243523384785325963094339728144811023266133546816860787405503371056873662508073284279180417626507724315776654624382665743082805910036891739754019932290977071276850239245644056698685966997752654383650764557358649666141576105936215709831181842086893228254304235678475375978464394818353375373451573
e = 830
c= 4413268199893347044741276120215584703428167052744516280494996526431559720190092261631829389527634625276020346166956540800884139234489942113764564139232948414263452549927818365096023041932432723988241639527832673120924732407691135173154085803338322715604275530735968992726708155724384432557207264839248502158712330572704509492520346044648676055223193900826626346707083590815897507927683083455678855000344499804465073698745769989966769567497677402668725931090596642504740789789740965769347050166069295727209131555338513809368814890255851742010120871635378654904140016065148709710206173069000137023824698858539843753921
'''
exp:
from Crypto.Util.number import *
import gmpy2,libnum

p = 171854505164939390402295426493389586289972154851849140728417624619463988154808053805729538974688869671559032639921300088271234681410193379381085714252211392886408792711387524667824537369266846649573070209815436507363007636943912350208275895292853801665488228125846058987049326903498661007035974420392738723323
q = 145951936627745243523384785325963094339728144811023266133546816860787405503371056873662508073284279180417626507724315776654624382665743082805910036891739754019932290977071276850239245644056698685966997752654383650764557358649666141576105936215709831181842086893228254304235678475375978464394818353375373451573
n = p*q
e = 830
c= 4413268199893347044741276120215584703428167052744516280494996526431559720190092261631829389527634625276020346166956540800884139234489942113764564139232948414263452549927818365096023041932432723988241639527832673120924732407691135173154085803338322715604275530735968992726708155724384432557207264839248502158712330572704509492520346044648676055223193900826626346707083590815897507927683083455678855000344499804465073698745769989966769567497677402668725931090596642504740789789740965769347050166069295727209131555338513809368814890255851742010120871635378654904140016065148709710206173069000137023824698858539843753921

e1 = e // 2
phi = (p-1)*(q-1)
d = gmpy2.invert(e1,phi)
m1 = pow(c,d,n)
m = gmpy2.iroot(m1,2)[0]
print(long_to_bytes(m))

这种方法比有限域开方的方法更简单

posted @ 2025-07-23 14:27  xiehou~  阅读(163)  评论(0)    收藏  举报