m1 = pow(c1,s1,n) m2 = pow(c2,s2,n) m = (m1*m2)%n print(m) #1021089710312311910410111011910111610410511010710511610511511211111511510598108101125 #flag需要是可见字符,所以不存在1开头的十位数,所以1开头的肯定是100以上的三位数,用ASCII码解 m_str = str(m) flag = "" i = 0 while i < len(m_str): if m_str[i] =='1': c = chr(int(m_str[i:i+3])) i += 3 else: c = chr(int(m_str[i:i+2])) i += 2
from Crypto.Util.number import * from gmpy2 import *
n = 21058339337354287847534107544613605305015441090508924094198816691219103399526800112802416383088995253908857460266726925615826895303377801614829364034624475195859997943146305588315939130777450485196290766249612340054354622516207681542973756257677388091926549655162490873849955783768663029138647079874278240867932127196686258800146911620730706734103611833179733264096475286491988063990431085380499075005629807702406676707841324660971173253100956362528346684752959937473852630145893796056675793646430793578265418255919376323796044588559726703858429311784705245069845938316802681575653653770883615525735690306674635167111
from Crypto.Util.number import * from gmpy2 import * import uuid import gmpy2 flag='LZSDS{'+str(uuid.uuid4())+'}'
e=2026 c = 13760578729891127041098229431259961120216468948795732373975536417751222443069805775693845560005881981622202089883866395577154701229046245882282127054969114210307175116574178428823043817041956207503299220721042136515863979655578210499512044917781566303947681251248645504273995402630701480590505840473412765662 n = 14247038211821385209759067256846232227444163173099199085257790370590450749665206556163364754269182255358084948354345827898987234756662133974633117062902370811855466665351784027125333112663075085395676501121759786699720149098576433141817737564928779420725539793335830274229206316999461309927000523188222801659 hint1 = 8938538619961731399716016665470564084986243880394928918482374295814509353382364651201249532111268951793354572124324033902502588541297713297622432670722730 hint2 = 1493298155243474837320092849325750387759519643879388609208314494000605554020636706320849032906759121914762492378489852575583260177546578935320977613050647 # hint1 = p ^ q ---> hint1 = p ^ hint2 # hint2 = q p ^ q ^ q = q q = hint2 p = hint1 ^ hint2 #按位异或
n = p * q #模数n
phi = (p - 1) * (q - 1) #计算n的欧拉函数
k = gcd(e,phi) #e和phi的最大公约数 print(k)
d = gmpy2.invert(e//k, phi) #整除 m = pow(c, d, n)
flag = long_to_bytes(gmpy2.iroot(m,k)[0]) #gmpy2.iroot(m,k)[0] --->m 的k次根 print(flag)
''' 方式2: flag = gmpy2.iroot(m,k)[0] print(long_to_bytes(flag)) '''
运算明文m = pow(c,d,n)公式为 $$ M = C^dmodN $$ gmpy2.iroot(m,k)[0] —>计算m的整数k次根,并返回到元组(r,is_exact)中。
三、dp、dq泄露
[1]BUUCTF RSA2
题干:
1 2 3 4 5
e = 65537 n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113 dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657
c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
from Crypto.Util.number import * import gmpy2 import libnum
e = 65537 n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113 dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657
p = 13468634736343473907717969603434376212206335187555458742257940406618189481177835992217885676243155145465521141546915941147336786447889325606555333350540003 q = 18432009829596386103558375461387837845170621179295293289126504231317130550979989727125205467379713835047300158256398009229511746203459540859429194971855371
c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751 n = p * q phi = (p-1) * (q-1) d = gmpy2.invert(e,phi) m = gmpy2.powmod(c,d,n) print(long_to_bytes(m))
p = libnum.generate_prime(1024) q = libnum.generate_prime(1024) e = 65537 n = p * q phi_n = (p - 1) * (q - 1) d = libnum.invmod(e, phi_n) dp = d % (p - 1) m = "" # m已经被出题人删除 m = libnum.s2n(m) n = p * q c = pow(m, e, n)
print("n=", n) print("e=", e) print("dp=", dp) print("c=", c)
e = 65537 for i inrange(1, e): if (dp * e - 1) % i == 0: if n % (((dp * e - 1) // i) + 1) == 0: p = ((dp * e - 1) // i) + 1 q = n // (((dp * e - 1) // i) + 1) phi = (q - 1) * (p - 1) d = gmpy2.invert(e, phi) m = pow(c, d, n)
—–BEGIN PUBLIC KEY—– MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMAzLFxkrkcYL2wch21CM2kQVFpY9+7+ /AvKr1rzQczdAgMBAAE= —–END PUBLIC KEY—–
公钥解析
爆破出p,q
1 2 3 4 5 6 7 8 9 10
import gmpy2 import rsa
e = 65537 n = 86934482296048119190666062003494800588905656017203025617216654058378322103517 p = 285960468890451637935629440372639283459 q = 304008741604601924494328155975272418463 phi = (p-1)*(q-1) d = gmpy2.invert(e,phi) print('d=',d)
n = 175797137276517400024170861198192089021253920489351812147043687817076482376379806063372376015921 c = 144009221781172353636339988896910912047726260759108847257566019412382083853598735817869933202168 p = 9401433281508038261 q = 10252499084912054759 r = 11215197893925590897 s = 11855687732085186571 t = 13716847112310466417 phi = (p-1)*(q-1)*(r-1)*(s-1)*(t-1)
from Crypto.Util.number import * from Crypto.Util.Padding import *
FLAG = bytes_to_long(pad(b"flag{??????}", 64))
definit_key(): p, q = getPrime(512), getPrime(512) n = p * q e = 9 while (GCD((p - 1) * (q - 1), e) != 1): p, q = getPrime(512), getPrime(512) n = p * q d = inverse(e, (p - 1) * (q - 1)) return n, e, d
n_list = list() c_list = list() for i inrange(9): N, e, d = init_key() n_list.append(N) c = pow(FLAG, e, N) c_list.append(pow(FLAG, e, N)) assert (pow(c, d, N) == FLAG) print("n_list:", n_list) print("c_list:", c_list) ''' n_list: [71189786319102608575263218254922479901008514616376166401353025325668690465852130559783959409002115897148828732231478529655075366072137059589917001875303598680931962384468363842379833044123189276199264340224973914079447846845897807085694711541719515881377391200011269924562049643835131619086349617062034608799, 92503831027754984321994282254005318198418454777812045042619263533423066848097985191386666241913483806726751133691867010696758828674382946375162423033994046273252417389169779506788545647848951018539441971140081528915876529645525880324658212147388232683347292192795975558548712504744297104487514691170935149949, 100993952830138414466948640139083231443558390127247779484027818354177479632421980458019929149817002579508423291678953554090956334137167905685261724759487245658147039684536216616744746196651390112540237050493468689520465897258378216693418610879245129435268327315158194612110422630337395790254881602124839071919, 59138293747457431012165762343997972673625934330232909935732464725128776212729547237438509546925172847581735769773563840639187946741161318153031173864953372796950422229629824699580131369991913883136821374596762214064774480548532035315344368010507644630655604478651898097886873485265848973185431559958627423847, 66827868958054485359731420968595906328820823695638132426084478524423658597714990545142120448668257273436546456116147999073797943388584861050133103137697812149742551913704341990467090049650721713913812069904136198912314243175309387952328961054617877059134151915723594900209641163321839502908705301293546584147, 120940513339890268554625391482989102665030083707530690312336379356969219966820079510946652021721814016286307318930536030308296265425674637215009052078834615196224917417698019787514831973471113022781129000531459800329018133248426080717653298100515701379374786486337920294380753805825328119757649844054966712377, 72186594495190221129349814154999705524005203343018940547856004977368023856950836974465616291478257156860734574686154136925776069045232149725101769594505766718123155028300703627531567850035682448632166309129911061492630709698934310123778699316856399909549674138453085885820110724923723830686564968967391721281, 69105037583161467265649176715175579387938714721653281201847973223975467813529036844308693237404592381480367515044829190066606146105800243199497182114398931410844901178842049915914390117503986044951461783780327749665912369177733246873697481544777183820939967036346862056795919812693669387731294595126647751951, 76194219445824867986050004226602973283400885106636660263597964027139613163638212828932901192009131346530898961165310615466747046710743013409318156266326090650584190382130795884514074647833949281109675170830565650006906028402714868781834693473191228256626654011772428115359653448111208831188721505467497494581] c_list: [62580922178008480377006528793506649089253164524883696044759651305970802215270721223149734532870729533611357047595181907404222690394917605617029675103788705320032707977225447998111744887898039756375876685711148857676502670812333076878964148863713993853526715855758799502735753454247721711366497722251078739585, 46186240819076690248235492196228128599822002268014359444368898414937734806009161030424589993541799877081745454934484263188270879142125136786221625234555265815513136730416539407710862948861531339065039071959576035606192732936477944770308784472646015244527805057990939765708793705044236665364664490419874206900, 85756449024868529058704599481168414715291172247059370174556127800630896693021701121075838517372920466708826412897794900729896389468152213884232173410022054605870785910461728567377769960823103334874807744107855490558726013068890632637193410610478514663078901021307258078678427928255699031215654693270240640198, 14388767329946097216670270960679686032536707277732968784379505904021622612991917314721678940833050736745004078559116326396233622519356703639737886289595860359630019239654690312132039876082685046329079266785042428947147658321799501605837784127004536996628492065409017175037161261039765340032473048737319069656, 1143736792108232890306863524988028098730927600066491485326214420279375304665896453544100447027809433141790331191324806205845009336228331138326163746853197990596700523328423791764843694671580875538251166864957646807184041817863314204516355683663859246677105132100377322669627893863885482167305919925159944839, 2978800921927631161807562509445310353414810029862911925227583943849942080514132963605492727604495513988707849133045851539412276254555228149742924149242124724864770049898278052042163392380895275970574317984638058768854065506927848951716677514095183559625442889028813635385408810698294574175092159389388091981, 16200944263352278316040095503540249310705602580329203494665614035841657418101517016718103326928336623132935178377208651067093136976383774189554806135146237406248538919915426183225265103769259990252162411307338473817114996409705345401251435268136647166395894099897737607312110866874944619080871831772376466376, 31551601425575677138046998360378916515711528548963089502535903329268089950335615563205720969393649713416910860593823506545030969355111753902391336139384464585775439245735448030993755229554555004154084649002801255396359097917380427525820249562148313977941413268787799534165652742114031759562268691233834820996, 25288164985739570635307839193110091356864302148147148153228604718807817833935053919412276187989509493755136905193728864674684139319708358686431424793278248263545370628718355096523088238513079652226028236137381367215156975121794485995030822902933639803569133458328681148758392333073624280222354763268512333515] '''
from Crypto.Util.number import * from gmpy2 import *
# from shin import flag
m = bytes_to_long(b'HDCTF{******}') e = 65537 p = getPrime(256) q = getPrime(512) r = getPrime(512) n = p * q * r ## phi=(p-1)*(q-1)*(r-1) P = pow(p, 2, n) ## P=p**2 p=iroof(P,2) Q = pow(q, 2, n) ## Q=q**2 q=iroof(Q,2) c = pow(m, e, n) ## 求d,d = gmpy2.invert(e, phi) print(f"P = {P}") print(f"Q = {Q}") print(f"n = {n}") print(f"c = {c}")
P = 8760210374362848654680470219309962250697808334943036049450523139299289451311563307524647192830909610600414977679146980314602124963105772780782771611415961 Q = 112922164039059900199889201785103245191294292153751065719557417134111270255457254419542226991791126571932603494783040069250074265447784962930254787907978286600866688977261723388531394128477338117384319760669476853506179783674957791710109694089037373611516089267817074863685247440204926676748540110584172821401 n = 12260605124589736699896772236316146708681543140877060257859757789407603137409427771651536724218984023652680193208019939451539427781667333168267801603484921516526297136507792965087544395912271944257535087877112172195116066600141520444466165090654943192437314974202605817650874838887065260835145310202223862370942385079960284761150198033810408432423049423155161537072427702512211122538749 c = 7072137651389218220368861685871400051412849006784353415843217734634414633151439071501997728907026771187082554241548140511778339825678295970901188560688120351732774013575439738988314665372544333857252548895896968938603508567509519521067106462947341820462381584577074292318137318996958312889307024181925808817792124688476198837079551204388055776209441429996815747449815546163371300963785
p = iroot(P,2)[0] q = iroot(Q,2)[0] r = n//p//q phi = (p-1) * (q-1)*(r-1) d = inverse(e,phi) m = pow(c,d,n) print(long_to_bytes(m))
from Crypto.Util.number import * from sympy import * from fractions import * from gmpy2 import * c = 7922547866857761459807491502654216283012776177789511549350672958101810281348402284098310147796549430689253803510994877420135537268549410652654479620858691324110367182025648788407041599943091386227543182157746202947099572389676084392706406084307657000104665696654409155006313203957292885743791715198781974205578654792123191584957665293208390453748369182333152809882312453359706147808198922916762773721726681588977103877454119043744889164529383188077499194932909643918696646876907327364751380953182517883134591810800848971719184808713694342985458103006676013451912221080252735948993692674899399826084848622145815461035 z = 32115748677623209667471622872185275070257924766015020072805267359839059393284316595882933372289732127274076434587519333300142473010344694803885168557548801202495933226215437763329280242113556524498457559562872900811602056944423967403777623306961880757613246328729616643032628964072931272085866928045973799374711846825157781056965164178505232524245809179235607571567174228822561697888645968559343608375331988097157145264357626738141646556353500994924115875748198318036296898604097000938272195903056733565880150540275369239637793975923329598716003350308259321436752579291000355560431542229699759955141152914708362494482 n = 15310745161336895413406690009324766200789179248896951942047235448901612351128459309145825547569298479821101249094161867207686537607047447968708758990950136380924747359052570549594098569970632854351825950729752563502284849263730127586382522703959893392329333760927637353052250274195821469023401443841395096410231843592101426591882573405934188675124326997277775238287928403743324297705151732524641213516306585297722190780088180705070359469719869343939106529204798285957516860774384001892777525916167743272419958572055332232056095979448155082465977781482598371994798871917514767508394730447974770329967681767625495394441 e=65537
x = iroot(z+2*n,2)[0] y = iroot(z-2*n,2)[0]
p = (x+y)//2 q = x-p n=p*q phi = (p-1)*(q-1)
d = inverse(e,phi) m = pow(c,d,n) print(long_to_bytes(m))
from Crypto.Util.number import * from gmpy2 import * from sympy import * p = 797862863902421984951231350430312260517773269684958456342860983236184129602390919026048496119757187702076499551310794177917920137646835888862706126924088411570997141257159563952725882214181185531209186972351469946269508511312863779123205322378452194261217016552527754513215520329499967108196968833163329724620251096080377748737 q = 797862863902421984951231350430312260517773269684958456342860983236184129602390919026048496119757187702076499551310794177917920137646835888862706126924088411570997141257159563952725882214181185531209186972351469946269508511312863779123205322378452194261217016552527754513215520329499967108196968833163329724620251096080377747699
from Crypto.Util.number import * from gmpy2 import *
n = 536970330703 p = 992623 q = 540961 e = 65537 c_list = [473878130775,40132555282,40132555282,94619939727,72818765591,208015808884,42561234694,159353248388,27748063975,159353248388,159353248388,278953790403,410746718603,496849210942,27748063975,142521857906,103632267191,17774494147,328684046745,278953790403,129956887006,129956887006,366275425558,328684046745,142521857906,410746718603,142521857906,129956887006,379067009467,328684046745,159353248388,366275425558,129956887006,103632267191,27748063975,27748063975,17774494147,160623996897,278953790403,182341799525]
phi = (p-1)*(q-1) d = inverse(e,phi) m_ = b''
for c in c_list: m = pow(c,d,n) m_ += long_to_bytes(m) print(m_)
巨简单的一题
[欧拉函数]NSSCTF HGAME Multi Prime RSA
(来自大佬的知识灌输)
题目:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
from Crypto.Util.number import getPrime from libnum import s2n from secret import flag
p = getPrime(256) q = getPrime(256) r = getPrime(256) s = getPrime(256) n = p ** 2 * q ** 3 * r ** 5 * s ** 7 e = 65537 c = pow(s2n(flag), e, n) print(f"p = {p}") print(f"q = {q}") print(f"r = {r}") print(f"s = {s}") print(f"n = {n}") print(f"e = {e}") print(f"c = {c}")
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
from Crypto.Util.number import * from gmpy2 import *
p = 61789932148719477384027458333380568978056286136137829092952317307711908353477 q = 91207969353355763685633284378833506319794714507027332929290701748727534193861 r = 105471299607375388622347272479207944509670502835651250945203397530010861809367 s = 83153238748903772448138307505579799277162652151244477391465130504267171881437 n = 1039344372165087100001063920598151812324151064684841845250974758525265148567706103784958424873181721352440209284812493753972556519482026327282644619091466886523804841248277210353173383407944598453848113815866908595335619458549486958764490103808475329598085842184963065068499489886467911087295087163762599284622055185456905774507245781667293199205317692029829495961487347944813874415423771980660778986211145841712412631156369129146470119135136378158203459576596246169191419488560832734046076107673091995860021863239882608638458149930255944184863801278386551031980146460231515747754411678651752698881001464973981424240781413084941947261875289725538959720572496329348499870580057997540844488309111059240745081048324762866572948371222839278718034435739827677190025500802453626872356208612718417249649474571197167076916403582394186357812640566250930361276229969553128128312736245440129556020108188835966131425956431796417720436474093381770796431629523054378258497546013222494974549262140415585158985940966415459478150722832119691308697510189026447359189994055885090735411738332296254011208547676914004864732327863884217733456287369771087094514708468685641820375220835485053482570852619363091173324203334503461823983610886849930944250553928855506012684504211525542998575275626784129736345142772399109273619522445919 e = 65537 c = 844677395496466411520394190869787261209960246734415406217975986418865760680024542119231873259131861208878522030009923057991526761346423130242121884493257732067700857897379859545356609151834223804262174935191718271211809221730601602827122249238086030580971376104724987801049500689134122609834321586609223761140538079460830213824674361601046367637227094018381901291488659642720549583856812747877519600804325570421770575999289389175021646347371879234023647657507178519047236746071420327155188213839293382288787853777540226192644761028822256165706787395891134765908229036044468473519166141610604791485071702808854944672418124203289328124793348198048601338476086482318248264508789781967910205393740835345086784345145351367491197717933757414967811594913692588314161669333147733048171044386546892346475181197482702164468542430187885074163177843285948999943328049159021873821254267471067523609151007885131921896462161216356454116929796355815756642621369974260365378070336290542971599886325232821981080341858950609157813769416455337935096696635623426418166316737131174435618543058086342714723330814586496030805366321181723292731710369013923285787724941830672247377301048663929453294620044701627159066468762709113137517559435822623284148112827473010030736329596829357275518641576798298066541516764673029908084962144713
phi = p**(2-1)*(p-1)*q**(3-1)*(q-1)*r**(5-1)*(r-1)*s**(7-1)*(s-1) d = inverse(e,phi) m = pow(c,d,n) print(long_to_bytes(m))
# 维纳攻击 import gmpy2 import primefac from Crypto.Util.number import *
deftransform(x,y): #使用辗转相处将分数 x/y 转为连分数的形式 res=[] while y: res.append(x//y) x,y=y,x%y return res defcontinued_fraction(sub_res): numerator,denominator=1,0 for i in sub_res[::-1]: #从sublist的后面往前循环 denominator,numerator=numerator,i*numerator+denominator return denominator,numerator #得到渐进分数的分母和分子,并返回
#求解每个渐进分数 defsub_fraction(x,y): res=transform(x,y) res=list(map(continued_fraction,(res[0:i] for i inrange(1,len(res))))) #将连分数的结果逐一截取以求渐进分数 return res
defwienerAttack(e,n): for (d,k) in sub_fraction(e,n): #用一个for循环来注意试探e/n的连续函数的渐进分数,直到找到一个满足条件的渐进分数 if k==0: #可能会出现连分数的第一个为0的情况,排除 continue if (e*d-1)%k!=0: #ed=1 (mod φ(n)) 因此如果找到了d的话,(ed-1)会整除φ(n),也就是存在k使得(e*d-1)//k=φ(n) continue phi=(e*d-1)//k #这个结果就是 φ(n) px,qy=get_pq(1,n-phi+1,n) if px*qy==n: p,q=abs(int(px)),abs(int(qy)) #可能会得到两个负数,负负得正未尝不会出现 d=gmpy2.invert(e,(p-1)*(q-1)) #求ed=1 (mod φ(n))的结果,也就是e关于 φ(n)的乘法逆元d return d print("该方法不适用") c = e = n = d=wienerAttack(e,n) print("d=",d) m = pow(c,d,n) print("flag = ",long_to_bytes(m))
# ------------------ 构造多项式方程 ------------------ # 设 p = p_high << kbits + x,其中 x 是未知的低位部分 # 目标是找到 x,使得 p | n(即 p 是 n 的因子)
# 定义多项式环(在模 n 下) PR.<x> = PolynomialRing(Zmod(n))
# 构造方程:f(x) = (p_high << kbits) + x p_high_shifted = p_high << kbits f = x + p_high_shifted
# ------------------ 使用 Coppersmith 方法求解小根 x ------------------ # X = 2^kbits 是 x 的上界 # beta = 0.4 是调整参数(如果失败,可以尝试 0.3~0.5) roots = f.small_roots(X=2^kbits, beta=0.4)
if not roots: print("[!] 未能找到解,尝试调整 beta 或检查输入位数是否足够") else: x0 = roots[0] print(f"[+] 找到解 x0 = {x0}")
# 恢复完整的 p p = p_high_shifted + x0 print(f"[+] 恢复的 p = {hex(p)}")
# 验证 p 是否确实是 n 的因子 if n % p == 0: print("[✓] 验证成功:p 是 n 的因子") q = n // p print(f"[+] 对应的 q = {hex(q)}") else: print("[!] 验证失败:恢复的 p 不是 n 的因子,请检查输入或调整参数")
# 恢复完整的 p p = p_high_shifted + x0 print(f"[+] 恢复的 p = {hex(p)}")
# 验证 p 是否确实是 n 的因子 if n % p == 0: print("[✓] 验证成功:p 是 n 的因子") q = n // p print(f"[+] 对应的 q = {hex(q)}") else: print("[!] 验证失败:恢复的 p 不是 n 的因子,请检查输入或调整参数")