Below is a collection of the basic / easy rsa challenges that I authored for the guided CTF hosted by Securinets ISI.
RSA01
description : RSA is a public-key cryptography algorithm that encrypts and decrypts data securely using a pair of keys: a public key for encryption and a private key for decryption. Attacking RSA in a CTF often involves exploiting weak key generation, small encryption exponents, or insufficient padding to factorize the modulus or recover plaintext. Can you break my encryption and retrieve the flag?
Data : n = 133057759405410196713996577614776585137 c = 81027466694039655654338302697352619188 e = 65537` For this challenge the modulus n is too small that it’s easy to factorise it using factordb and retrieve p&q then calculate the private key d to finally recover the flag.
Solver :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
from Crypto.Util.number import long_to_bytes, inverse
n = 133057759405410196713996577614776585137 c = 81027466694039655654338302697352619188 e=65537 p,q=9408799956350366153 , 14141841682541493929
r=(p-1)*(q-1) d=inverse(e,r)
m=pow(c,d,n) f=long_to_bytes(m).decode('utf-8') print("Securinets{" + f +"}")
RSA02 description : if I use one prime only for N , you wont be able to factorise it ! im so smartttt
Data :
c = 118282453994915067115533072330204791590985623652958941724778500771132309209861471374977196484899695310790041029397945228312122466853334812707185314591133611995735076734093397710259825632388059828239146185365391425927762196807431151021766050491656240686821887089991313147120177642109805744451402690972638232208 e = 65537 n = 146943159688355173703916100543422379050357054115445990235972218469195431271709113288070841431038332725248398306543010191587575795114347455545117361096054023707807481731708102069920173598906378778376470955147300891620899721367733561338236185018799014766984757756587631920968288449973827629341343486711607539921
because the decription itself is a hint, we can guess that N is a prime itself instead of a product of 2 primes , as if N=p Therefore the euler tuition is simply phi=N-1
Solver :
1 2 3 4 5 6 7 8 9
from Crypto.Util.number import bytes_to_long, inverse, getPrime, long_to_bytes
c = 118282453994915067115533072330204791590985623652958941724778500771132309209861471374977196484899695310790041029397945228312122466853334812707185314591133611995735076734093397710259825632388059828239146185365391425927762196807431151021766050491656240686821887089991313147120177642109805744451402690972638232208 e = 65537 n = 146943159688355173703916100543422379050357054115445990235972218469195431271709113288070841431038332725248398306543010191587575795114347455545117361096054023707807481731708102069920173598906378778376470955147300891620899721367733561338236185018799014766984757756587631920968288449973827629341343486711607539921
RSA03 description : A 1024bit prime wasnt enough , and the 2048bit takes too long to generate , so I generated one and used it 4 times hehe. my number is real huge rn ;)
‘I generated one and used it 4 times’ , which indicated that N=pppp = p^4. In this case we can find the prime factor p by simply calculating the 4th root of N , then we will calculate the euler tuition.
Solver :
1 2 3 4 5 6 7 8 9 10 11 12 13
from Crypto.Util.number import bytes_to_long, inverse, getPrime, long_to_bytes from gmpy2 import iroot
c = 19134745275853194244503274030795421762751522415696767603261669936071405459005384769933434710016779543250956707812515094242574018194676257513764291640739637309694951402828389416196073330414030135316532127299164661461474466434106368166999042073035142601932114669993593582411556895863088075301414562257356600771140910874483259543923293638309986862599629911582061638816509857936693518316412641347185821933608716580148400006401584742030822994147694241279316996591456664764737966681902295961926719060406235766606530307906506074485147282109688652355764806745553846746779646486597458061805223119273617165510995444554998268468874307672361703832102277193553679673692510833348067984482250484583338427925466915171553404439378058589942892381199700348848022611900428310003322115381408422036941535865665887921366450355836640142336602494339843279385799585879384270232349283820447079412271069818218270110241826564255120098584111318288430261753943145918587034365416019965883765680504984000188761691359835653829745238783563320399591988226758980384470312668504399659973823873261718201972875706351891914040829153312712321376733222848656886532703469789894802853336793333587780004201380642692503186996380817503106542224474497677602589165653715186120472831653772899406800617990546004685231074474016455622030766175230542323511603645779349776320687647782989555722351567812720275957035955713690580718363542019151662368656349235353024384408586125497942783549553366432135316578559767620628474591570042765570502787364092210441075517313747151023052828908012962493966179623817478013636123056309724947968928001628469554672746997334694399453407073352436232841177718541650831215548465194385987720273170127921998145033469088644718754568068589999917296585075509866617086721328472864032016169372044916913568308581975830533258753677823378594543675756192508593533071127225858748419752355485678532217980337921689114893700448665412605161836395286763278088419297135767885275429085504661521633338134682593982675900569599430604042620687759836512684341682214118449025211639283776711115058149520971897921057079853857180649140825993343170303404545002448497759417414073836846420361307212351060369454934412990805030668440777112010054084050937719775132115870996431439278724822483664871764668734189553831000276582043520582966990862068736337014548798536326291199778030654958378054562753153183372668976075876664527759936152033089946958596486758352916448970690711702660954951507225274987257069677595630433666360937263088 e = 65537 n = 306607703391320056991513508753308666153844616701220871565567756535824442282020363654415017648287251418094948471550721510037817600354749031881292195025406884692963700853082836342568071081951327706971115819281677838267390893991115539454288086702195434281355343619618384963825082359923650376320707789535190216598886030782420201576372735472846975776891369441574236016694997945723166091024648343784719987678665417742217723228683101937082381061495252534905641610948072185757521700996820771253130256458431942937333222650601683491131174738247428266245587715749268238567846848723750778583206864060883545651183065329378774513614421500810990646535914591292953834490895542003777329054349717336728425248606309121611741566970489617677135004159364622510578671731155482755204795488150582666826594815791827689938675588977014320493667724140798567593974467195612351641352821702608556208775886482402907121023951693671323224679951727350959171944188688071550863511898397630553811189832564079579629859889126727205984841758587102825319022596325639974797827574130433192129922592125010908650175541115118252562154312855169609325513287696798639123259558384419082401559053867350286614651244167035643395835740987173693898941458094990621921731496148857527612123684720960000136425151047602273023138303135724647435930867481448233415635808109081172409980120573832791835162285828159598816252756809472054818599964619598004591754297393230007485296961651219928823707247431240313353642276735463786408483029377933033483173144720685398779473515484401913186710254190339831086747555652846170407711005445543290791822618993177939691776427979912746356355961781647172838349637813974986583013385191267088443242447648749480582697865171526854170867597938964948870978085979341683359085281848837171075345862242407732720429704596398726720581518807680912958669346224310775018193087642493531223643966222760512022136216924920976230463472478535799051380627345641642961713950476476243597167257713788697626216765556628995341269402205739928534509840720613601576820130781078109813406005673934688266607419655030801551599161922821939673577854460859643758941300319382438968910009093849410629473541672099732013280418462853503735213490678742707026205836833420926495325213943579367574987100085697983198275030082560049690384976104792045980946826660325555300100458514124012186157762882147441224700639367534144490333422997269694354445625952469391662795976652735323290855263245162753910469341528457898090564341771082201316338022681886321 p=iroot(n,4)[0] phi=(p**3)*(p-1)
d=inverse(e,phi) print(long_to_bytes(pow(c,d,n)))
RSA04
description : you’ve got tricks huh, no worries , I’ll get diffrent large keys this time, but gotta use a small exponent to make the process faster
Data : c = 1537150285716227605031838934788141177886658836535923894763771788997502746013878586588514967177576918221488975252570099470296450911774897636944014027191763 e = 3 n = 6146786767906341640151717109352619305048516049635186076371517569989570692234448672669878631257842691410568891710875462548373242004652600229150965897359313 len_flag = 22
For this challenge we can see that n is too large however the exponent being too small is our attack vector. if m^e was smaller than n, we could’ve simply calculated the e’th root of of c, but that’s not the case here , so we need to loop over the c+i*N until we get the correct value of m, and knowing the bit length of the actual message we can narrow down the bruteforce range to gain time.
from Crypto.Util.number import bytes_to_long, inverse, getPrime, long_to_bytes from gmpy2 import iroot
c = 1537150285716227605031838934788141177886658836535923894763771788997502746013878586588514967177576918221488975252570099470296450911774897636944014027191763 e = 3 n = 6146786767906341640151717109352619305048516049635186076371517569989570692234448672669878631257842691410568891710875462548373242004652600229150965897359313 len_flag = 22
val = ( (len_flag * 8) - 4 ) * e print(val) min = 1 << val max = 1 << (8 * e * (len_flag))
i = 0 while c < min: c += n i += 1
counter = 0
while c < max: root , ismultiple = iroot(c,e) if ismultiple: try: print('Securinets{' + long_to_bytes(root).decode('utf-8') + '}') print(f"counter: {counter}") except UnicodeDecodeError: pass c += n counter+= 1 print('ended')
RSA05
description :I’m tired of people asking me the same question everytime and I have to generate a new key for each one of them >:( Data :
Damn those lists are huge, with 13 Ns and Cs. The description indicated that those ciphers come from the same message m, which hints at the Hastad’s Broadcast Attack since e wasn’t given , the default solution would be that e is equal to the number of Ns and Cs in the list , which is e=13
#!/usr/bin/env python3 from Crypto.Util.number import long_to_bytes
classBroadcastAttack:
t = [] messsage = 0 def__init__(self, e, N, C): self.e = e self.N = N self.C = C
defcalculate_partials(self): for i inrange(self.e): mod_product = 1 for j inrange(self.e): if i != j: mod_product *= self.N[j] t_i = self.C[i]*mod_product*ModUtil.modinv(mod_product, self.N[i]) self.t.append(t_i)
defsolve_congruence(self): partial_total = 0 mod_product = 1 for i inrange(self.e): partial_total += self.t[i] mod_product *= self.N[i]