CTF中RSA相关题型总结(持续更新)
e很小时:
import gmpy2 from functools import reduce from Crypto.Util.number import long_to_bytes def CRT(items): N = reduce(lambda x, y: x * y, (i[1] for i in items)) result = 0 for a, n in items: m = N // n d, r, s = gmpy2.gcdext(n, m) if d != 1: raise Exception("Input not pairwise co-prime") result += a * s * m return result % N, N # e, n, c e = 0x3 n=[0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793] c=[0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365] data = list(zip(c, n)) x, n = CRT(data) m = gmpy2.iroot(gmpy2.mpz(x), e)[0].digits() print(m) print(long_to_bytes(int(m)).decode())
解形如 的同余方程
V&N2020 公开赛 easy_RSA
from random import randint from gmpy2 import * from Crypto.Util.number import * def getprime(bits): while 1: n = 1 while n.bit_length() < bits: n *= next_prime(randint(1,1000)) if isPrime(n - 1): return n - 1 m = bytes_to_long(b'flag{************************************}') p = getprime(505) q = getPrime(512) r = getPrime(512) assert m < q n = p * q * r e = 0x10001 d = invert(q ** 2, p ** 2) c = pow(m, 2, r) cipher = pow(c, e, n) print(n) print(d) print(cipher) ''' 7941371739956577280160664419383740967516918938781306610817149744988379280561359039016508679365806108722198157199058807892703837558280678711420411242914059658055366348123106473335186505617418956630780649894945233345985279471106888635177256011468979083320605103256178446993230320443790240285158260236926519042413378204298514714890725325831769281505530787739922007367026883959544239568886349070557272869042275528961483412544495589811933856131557221673534170105409 7515987842794170949444517202158067021118454558360145030399453487603693522695746732547224100845570119375977629070702308991221388721952258969752305904378724402002545947182529859604584400048983091861594720299791743887521228492714135449584003054386457751933095902983841246048952155097668245322664318518861440 1618155233923718966393124032999431934705026408748451436388483012584983753140040289666712916510617403356206112730613485227084128314043665913357106301736817062412927135716281544348612150328867226515184078966397180771624148797528036548243343316501503364783092550480439749404301122277056732857399413805293899249313045684662146333448668209567898831091274930053147799756622844119463942087160062353526056879436998061803187343431081504474584816590199768034450005448200 '''
c = pow(m, 2, r)
from sympy.ntheory.residue_ntheory import nthroot_mod m=nthroot_mod(c,2,r)
完整exp:
from gmpy2 import * from Crypto.Util.number import * from sympy.ntheory.residue_ntheory import nthroot_mod p=102634610559478918970860957918259981057327949366949344137104804864768237961662136189827166317524151288799657758536256924609797810164397005081733039415393 q=7534810196420932552168708937019691994681052660068275906973480617604535381306041583841106383688654426129050931519275383386503174076258645141589911492908993 r=10269028767754306217563721664976261924407940883784193817786660413744866184645984238866463711873380072803747092361041245422348883639933712733051005791543841 e=65537 phi=(p-1)*(q-1)*(r-1) d=invert(e,phi) n=p*q*r cipher=1618155233923718966393124032999431934705026408748451436388483012584983753140040289666712916510617403356206112730613485227084128314043665913357106301736817062412927135716281544348612150328867226515184078966397180771624148797528036548243343316501503364783092550480439749404301122277056732857399413805293899249313045684662146333448668209567898831091274930053147799756622844119463942087160062353526056879436998061803187343431081504474584816590199768034450005448200 c=pow(cipher,d,n) m=nthroot_mod(c,2,r) print(long_to_bytes(m))
Rabin RSA:
import gmpy2 import libnum from Crypto.Util.number import long_to_bytes p=13934102561950901579 q=14450452739004884887 e = 2 c = 20442989381348880630046435751193745753 n = p*q # Rebin算法 mp = gmpy2.powmod(c, (p+1)//4, p) mq = gmpy2.powmod(c, (q+1)//4, q) gcd1, a, b= gmpy2.gcdext(p, q) # 欧几里得扩展a*p+b*q=gcd1 r=(a*p*mq+b*q*mp)%n r_=n-r s=(a*p*mq-b*q*mp)%n s_=n-s print(f"r={libnum.n2s(int(r))}") print(f"r_={libnum.n2s(int(r_))}") print(f"s={libnum.n2s(int(s))}") print(f"s_={libnum.n2s(int(s_))}")
pq生成不当:
from Crypto.Util.number import * import sympy #from secrets import flag def get_happy_prime(): p = getPrime(512) q = sympy.nextprime(p ^ ((1 << 512) - 1)) return p, q m = bytes_to_long(flag) p, q = get_happy_prime() n = p * q e = 65537 print(n) print(pow(m, e, n)) # 24852206647750545040640868093921252282805229864862413863025873203291042799096787789288461426555716785288286492530194901130042940279109598071958012303179823645151637759103558737126271435636657767272703908384802528366090871653024192321398785017073393201385586868836278447340624427705360349350604325533927890879 # 14767985399473111932544176852718061186100743117407141435994374261886396781040934632110608219482140465671269958180849886097491653105939368395716596413352563005027867546585191103214650790884720729601171517615620202183534021987618146862260558624458833387692782722514796407503120297235224234298891794056695442287
q等于p取反的下一个素数
则
则
则
所以我们可以构造
因此可以求出
因此可以求出p的值
exp1:(以p能不能整除n作为判断条件)
from Crypto.Util.number import * import gmpy2 n=24852206647750545040640868093921252282805229864862413863025873203291042799096787789288461426555716785288286492530194901130042940279109598071958012303179823645151637759103558737126271435636657767272703908384802528366090871653024192321398785017073393201385586868836278447340624427705360349350604325533927890879 c=14767985399473111932544176852718061186100743117407141435994374261886396781040934632110608219482140465671269958180849886097491653105939368395716596413352563005027867546585191103214650790884720729601171517615620202183534021987618146862260558624458833387692782722514796407503120297235224234298891794056695442287 t1=1<<512 p=(2**512+gmpy2.iroot((2**512)**2-4*n,2)[0])//2 p=int(p) while n%p!=0: p=gmpy2.next_prime(p) q=n//p phi=(p-1)*(q-1) d=gmpy2.invert(e,phi) m=pow(c,d,n) print(long_to_bytes(m))
exp2:(以
from Crypto.Util.number import * import gmpy2 n=24852206647750545040640868093921252282805229864862413863025873203291042799096787789288461426555716785288286492530194901130042940279109598071958012303179823645151637759103558737126271435636657767272703908384802528366090871653024192321398785017073393201385586868836278447340624427705360349350604325533927890879 c=14767985399473111932544176852718061186100743117407141435994374261886396781040934632110608219482140465671269958180849886097491653105939368395716596413352563005027867546585191103214650790884720729601171517615620202183534021987618146862260558624458833387692782722514796407503120297235224234298891794056695442287 for r in range(10000000000): t1=(1<<512)-1+r t2,s=gmpy2.iroot(t1**2-4*n,2) if s: p=(t1+t2)//2 q=n//p d=gmpy2.invert(e,(p-1)*(q-1)) print(long_to_bytes(pow(c,d,n))) break
使用sagemath的p,q=two_squares(N)
# #sage9.3 # from Crypto.Util.number import * # flag = b'Kicky_Mu{KFC_v_me_50!!!}' # p = getPrime(256) # q = getPrime(256) # n = p*q^3 # e = 0x10001 # N = pow(p, 2) + pow(q, 2) # m = bytes_to_long(flag) # c = pow(m,e,n) # # print(c) # print(N) from Crypto.Util.number import * c = 34992437145329058006346797890363070594973075282993832268508442432592383794878795192132088668900695623924153165395583430068203662437982480669703879475321408183026259569199414707773374072930515794134567251046302713509056391105776219609788157691337060835717732824405538669820477381441348146561989805141829340641 N = 14131431108308143454435007577716000559419205062698618708133959457011972529354493686093109431184291126255192573090925119389094648901918393503865225710648658 p,q=two_squares(N) n = p * pow(q, 3) e = 0x10001 phi = (p - 1) * (pow(q, 3) - pow(q, 2)) d = inverse(e, phi) m = pow(c, d, n) print(long_to_bytes(m))
Coppersmith
已知m的高位,求m
n=10934282759418716864083387149400358148885247110933867252983794425632302624483291838978054379912661191455027376539730843211768681711588034738804296785076819 c=199928678441564572513071545433948014294972061145992950128884609861283198064457810780158231851803305318741555460032075238932950496972965422017125 (m>>72)<<72=584734024210391580014049648429032467639773954048 e=3
在
exp:
from Crypto.Util.number import * def phase2(high_m, n, c): R.<x> = PolynomialRing(Zmod(n), implementation='NTL') m = high_m + x M = m((m^3 - c).small_roots()[0]) return M n = 10934282759418716864083387149400358148885247110933867252983794425632302624483291838978054379912661191455027376539730843211768681711588034738804296785076819 c = 199928678441564572513071545433948014294972061145992950128884609861283198064457810780158231851803305318741555460032075238932950496972965422017125 high_m = 584734024210391580014049648429032467639773954048 M=phase2(high_m, n, c) print(long_to_bytes(int(M)))
flag{this_is_a_flag}
已知p的高位,求m
n = 22251179507951667208988404735324990388496950479821651652239579051045817986824945842987389922759437945557559748313907295712994332924679954306619009079508267870910149223565520196385455171091011721532290110253401719887456896015127869765120008086727571060297059461651083340986173237394309195529977693665449059967337557768799655172974710341929078477027816362721220950313898766868468203962782247110726810571421671360963619837700834009507913757260784147014841481557088215597539779565493898663380798904766007590175316989637076522379230279938065198199833033309266088268398369881039750675835382713087914092008694800853680890199 c = 13791076590876280345965238373786427523823675722374540431144373789735114060078921115309660269509771288228144711168452947459244770278987545774287579571059845423259662466243727180866431665100157413245622442955953683599217851246153754699865188329020209657227990460455369896960050383820265224545863644175721361758413632638638545353172694886999221882770404353366722168355187142789778530832186215934690392286482192890311329246011772739859918291556448869621490688586398693159275264761107488552610343215662469995425523594866854716852872141401095283180173839653418794273521904566990987307557028155209305585359720312859989634334 (p>>128)<<128 = 150840505999598161819551431768821975459467574249752039047846845481249241887784911457438773307473629946085877682693884024926228559996574370474982369597013808808768450992113314638371133051992554697609546180277873202687064844984114775286878743211353292718680724328420518679703560272767696234210910831061812379648
exp:
from Crypto.Util.number import * def phase3(high_p, n, c): R.<x> = PolynomialRing(Zmod(n), implementation='NTL') p = high_p + x x0 = p.small_roots(X = 2^128, beta = 0.1,epsilon=0.02)[0] P = int(p(x0)) Q = n // P assert n == P*Q d = inverse_mod(65537, (P-1)*(Q-1)) #print(power_mod(c, d, n)) return power_mod(c,d,n) n = 22251179507951667208988404735324990388496950479821651652239579051045817986824945842987389922759437945557559748313907295712994332924679954306619009079508267870910149223565520196385455171091011721532290110253401719887456896015127869765120008086727571060297059461651083340986173237394309195529977693665449059967337557768799655172974710341929078477027816362721220950313898766868468203962782247110726810571421671360963619837700834009507913757260784147014841481557088215597539779565493898663380798904766007590175316989637076522379230279938065198199833033309266088268398369881039750675835382713087914092008694800853680890199 c = 13791076590876280345965238373786427523823675722374540431144373789735114060078921115309660269509771288228144711168452947459244770278987545774287579571059845423259662466243727180866431665100157413245622442955953683599217851246153754699865188329020209657227990460455369896960050383820265224545863644175721361758413632638638545353172694886999221882770404353366722168355187142789778530832186215934690392286482192890311329246011772739859918291556448869621490688586398693159275264761107488552610343215662469995425523594866854716852872141401095283180173839653418794273521904566990987307557028155209305585359720312859989634334 high_p = 150840505999598161819551431768821975459467574249752039047846845481249241887784911457438773307473629946085877682693884024926228559996574370474982369597013808808768450992113314638371133051992554697609546180277873202687064844984114775286878743211353292718680724328420518679703560272767696234210910831061812379648 M=phase3(high_p, n, c) print(M) print(long_to_bytes(M))
已知p的若干中间位
from Crypto.Util.number import * flag = b'?' e = 65537 p, q = getPrime(1024), getPrime(1024) N = p * q gift = p&(2**923-2**101) m = bytes_to_long(flag) c = pow(m, e, N) print("N = ",N) print("gift = ",gift) print("c = ",c) """ N = 12055968471523053394851394038007091122809367392467691213651520944038861796011063965460456285088011754895260428814358599592032865236006733879843493164411907032292051539754520574395252298997379020268868972160297893871261713263196092380416876697472160104980015554834798949155917292189278888914003846758687215559958506116359394743135211950575060201887025032694825084104792059271584351889134811543088404952977137809673880602946974798597506721906751835019855063462460686036567578835477249909061675845157443679947730585880392110482301750827802213877643649659069945187353987713717145709188790427572582689339643628659515017749 p0 = 70561167908564543355630347620333350122607189772353278860674786406663564556557177660954135010748189302104288155939269204559421198595262277064601483770331017282701354382190472661583444774920297367889959312517009682740631673940840597651219956142053575328811350770919852725338374144 c = 2475592349689790551418951263467994503430959303317734266333382586608208775837696436139830443942890900333873206031844146782184712381952753718848109663188245101226538043101790881285270927795075893680615586053680077455901334861085349972222680322067952811365366282026756737185263105621695146050695385626656638309577087933457566501579308954739543321367741463532413790712419879733217017821099916866490928476372772542254929459218259301608413811969763001504245717637231198848196348656878611788843380115493744125520080930068318479606464623896240289381601711908759450672519228864487153103141218567551083147171385920693325876018 """
exp:
N = 12055968471523053394851394038007091122809367392467691213651520944038861796011063965460456285088011754895260428814358599592032865236006733879843493164411907032292051539754520574395252298997379020268868972160297893871261713263196092380416876697472160104980015554834798949155917292189278888914003846758687215559958506116359394743135211950575060201887025032694825084104792059271584351889134811543088404952977137809673880602946974798597506721906751835019855063462460686036567578835477249909061675845157443679947730585880392110482301750827802213877643649659069945187353987713717145709188790427572582689339643628659515017749 p0 = 70561167908564543355630347620333350122607189772353278860674786406663564556557177660954135010748189302104288155939269204559421198595262277064601483770331017282701354382190472661583444774920297367889959312517009682740631673940840597651219956142053575328811350770919852725338374144 c = 2475592349689790551418951263467994503430959303317734266333382586608208775837696436139830443942890900333873206031844146782184712381952753718848109663188245101226538043101790881285270927795075893680615586053680077455901334861085349972222680322067952811365366282026756737185263105621695146050695385626656638309577087933457566501579308954739543321367741463532413790712419879733217017821099916866490928476372772542254929459218259301608413811969763001504245717637231198848196348656878611788843380115493744125520080930068318479606464623896240289381601711908759450672519228864487153103141218567551083147171385920693325876018 def bivariate(pol, XX, YY, kk=4): N = pol.parent().characteristic() f = pol.change_ring(ZZ) PR, (x, y) = f.parent().objgens() idx = [(k - i, i) for k in range(kk + 1) for i in range(k + 1)] monomials = list(map(lambda t: PR(x ** t[0] * y ** t[1]), idx)) # collect the shift-polynomials g = [] for h, i in idx: if h == 0: g.append(y ** h * x ** i * N) else: g.append(y ** (h - 1) * x ** i * f) # construct lattice basis M = Matrix(ZZ, len(g)) for row in range(M.nrows()): for col in range(M.ncols()): h, i = idx[col] M[row, col] = g[row][h, i] * XX ** h * YY ** i # LLL B = M.LLL() PX = PolynomialRing(ZZ, 'xs') xs = PX.gen() PY = PolynomialRing(ZZ, 'ys') ys = PY.gen() # Transform LLL-reduced vectors to polynomials H = [(i, PR(0)) for i in range(B.nrows())] H = dict(H) for i in range(B.nrows()): for j in range(B.ncols()): H[i] += PR((monomials[j] * B[i, j]) / monomials[j](XX, YY)) # Find the root poly1 = H[0].resultant(H[1], y).subs(x=xs) poly2 = H[0].resultant(H[2], y).subs(x=xs) poly = gcd(poly1, poly2) x_root = poly.roots()[0][0] poly1 = H[0].resultant(H[1], x).subs(y=ys) poly2 = H[0].resultant(H[2], x).subs(y=ys) poly = gcd(poly1, poly2) y_root = poly.roots()[0][0] return x_root, y_root PR = PolynomialRing(Zmod(N), names='x,y') x, y = PR.gens() pol = 2 ** 923 * x + y + p0 x, y = bivariate(pol, 2 ** 101, 2 ** 101) p = 2 ** 923 * x + y + p0 q = N // p print(p) print(q) phi=(p-1)*(q-1) e=65537 d=inverse(e,phi) m=pow(c,d,N) print(long_to_bytes(int(m)))
本文作者:Smera1d0
本文链接:https://www.cnblogs.com/Smera1d0/p/18191750
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步