RSA基础解题-CTF实例

1.前情提要

  • 密码学类的题很需要数学推导能力,同时还要了解很多数学定理(建议是多刷题然后整理,然后熟悉原理之后使用工具,推荐b站up主风二西的RSA工具)
  • 下面的RSA题目出自CTFSHOW-Crypto
  • 基础公式:

n=p*q

\varphi (n)=(p-1)*(q-1)

e*d\equiv 1\, mod\, \varphi (n):(n,e)是公钥 (n,d)是私钥

c=m^{e}\, mod\,n

m=c^{d}\, mod\,n


2.模运算的基本性质

模运算的概念和性质-CSDN博客

1.\; (a+b)\, mod\, c=(a\, mod\,c+b\,mod\,c)\,mod\,c

2.\; (a-b)\, mod\, c=(a\, mod\,c-b\,mod\,c)\,mod\,c

3.\;(a*b)\, mod\, c=(a\, mod\,c*b\,mod\,c)\,mod\,c

4.\;(a^{b})\, mod\, c=(a\, mod\,c)^{b}\,mod\,c

5.\;((a+b)\, mod\, p+c)\,mod\,p=(a+(b+c)\, mod\,p)\,mod\,p

6.\;((a*b)\, mod\, p*c)\,mod\,p=(a*(b*c)\, mod\,p)\,mod\,p

7.\;((a+b)\, mod\, p*c)\,mod\,p=((a*c)\, mod\,p+(b*c)\,mod\,p)\,mod\,p

3.CTF实例

babyrsa

这道题就是基础的RSA解密题,直接用公式就可得到flag

import gmpy2
from Crypto.Util.number import *
import libnum
e = 65537
p = 104046835712664064779194734974271185635538927889880611929931939711001301561682270177931622974642789920918902563361293345434055764293612446888383912807143394009019803471816448923969637980671221111117965227402429634935481868701166522350570364727873283332371986860194245739423508566783663380619142431820861051179
q = 140171048074107988605773731671018901813928130582422889797732071529733091703843710859282267763783461738242958098610949120354497987945911021170842457552182880133642711307227072133812253341129830416158450499258216967879857581565380890788395068130033931180395926482431150295880926480086317733457392573931410220501
c = 4772758911204771028049020670778336799568778930072841084057809867608022732611295305096052430641881550781141776498904005589873830973301898523644744951545345404578466176725030290421649344936952480254902939417215148205735730754808467351639943474816280980230447097444682489223054499524197909719857300597157406075069204315022703894466226179507627070835428226086509767746759353822302809385047763292891543697277097068406512924796409393289982738071019047393972959228919115821862868057003145401072581115989680686073663259771587445250687060240991265143919857962047718344017741878925867800431556311785625469001771370852474292194

d=gmpy2.invert(e,(p-1)*(q-1)) # 解法1
# d=libnum.invmod(e,(p-1)*(q-1)) # 和上面算出的结果是一样的
m=pow(c,d,p*q)
print(long_to_bytes(m).decode()) # flag{b4by_R5A}
# print(libnum.n2s(int(m)).decode()) # 和上面算出的结果是一样的

easyrsa1(N分解)

需要通过分解n去获取p和q,然后就RSA公式正常解出

1.在线分解网站:http://www.factordb.com/index.php

2.yafu工具:用于自动整数因式分解,适用p和q相差较大或相差较小时

yafu download | SourceForge.net

使用方法:

yafu-x64.exe factor(要分解的数n)

yafu-x64.exe "factor(@)" -batchfile 1.txt  // 如果数比较大,那就需要将数保存成一个txt,记得在文本最后加一个换行符,不然会报错

easyrsa2(N不互素:使用相同的素数p或q)

题目给了多个n和c,同样一个e,那么n之间可能是共享素数

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

e= 65537
n1= 23686563925537577753047229040754282953352221724154495390687358877775380147605152455537988563490716943872517593212858326146811511103311865753018329109314623702207073882884251372553225986112006827111351501044972239272200616871716325265416115038890805114829315111950319183189591283821793237999044427887934536835813526748759612963103377803089900662509399569819785571492828112437312659229879806168758843603248823629821851053775458651933952183988482163950039248487270453888288427540305542824179951734412044985364866532124803746008139763081886781361488304666575456680411806505094963425401175510416864929601220556158569443747
n2= 22257605320525584078180889073523223973924192984353847137164605186956629675938929585386392327672065524338176402496414014083816446508860530887742583338880317478862512306633061601510404960095143941320847160562050524072860211772522478494742213643890027443992183362678970426046765630946644339093149139143388752794932806956589884503569175226850419271095336798456238899009883100793515744579945854481430194879360765346236418019384644095257242811629393164402498261066077339304875212250897918420427814000142751282805980632089867108525335488018940091698609890995252413007073725850396076272027183422297684667565712022199054289711
c1= 1627484142237897613944607828268981193911417408064824540711945192035649088104133038147400224070588410335190662682231189997580084680424209495303078061205122848904648319219646588720994019249279863462981015329483724747823991513714172478886306703290044871781158393304147301058706003793357846922086994952763485999282741595204008663847963539422096343391464527068599046946279309037212859931303335507455146001390326550668531665493245293839009832468668390820282664984066399051403227990068032226382222173478078505888238749583237980643698405005689247922901342204142833875409505180847943212126302482358445768662608278731750064815
c2= 2742600695441836559469553702831098375948641915409106976157840377978123912007398753623461112659796209918866985480471911393362797753624479537646802510420415039461832118018849030580675249817576926858363541683135777239322002741820145944286109172066259843766755795255913189902403644721138554935991439893850589677849639263080528599197595705927535430942463184891689410078059090474682694886420022230657661157993875931600932763824618773420077273617106297660195179922018875399174346863404710420166497017196424586116535915712965147141775026549870636328195690774259990189286665844641289108474834973710730426105047318959307995062
#求最大公约数
q=gmpy2.gcd(n1,n2)
p1=n1//q
phi_n=(q-1)*(p1-1)
#求逆元d
d1=libnum.invmod(e,phi_n)
m=pow(c1,d1,n1)
print(m)
#数字转字节,转字符串
print(libnum.n2s(int(m)).decode()) # flag{m0_bv_hv_sv}

easyrsa3(共模攻击)

题目给了同一个n,不同的c和e。且e1和e2互质(即gcd(e1,e2)=1)

e1 = 797
n1 = 15944475431088053285580229796309956066521520107276817969079550919586650535459242543036143360865780730044733026945488511390818947440767542658956272380389388112372084760689777141392370253850735307578445988289714647332867935525010482197724228457592150184979819463711753058569520651205113690397003146105972408452854948512223702957303406577348717348753106868356995616116867724764276234391678899662774272419841876652126127684683752880568407605083606688884120054963974930757275913447908185712204577194274834368323239143008887554264746068337709465319106886618643849961551092377843184067217615903229068010117272834602469293571
c1 = 11157593264920825445770016357141996124368529899750745256684450189070288181107423044846165593218013465053839661401595417236657920874113839974471883493099846397002721270590059414981101686668721548330630468951353910564696445509556956955232059386625725883038103399028010566732074011325543650672982884236951904410141077728929261477083689095161596979213961494716637502980358298944316636829309169794324394742285175377601826473276006795072518510850734941703194417926566446980262512429590253643561098275852970461913026108090608491507300365391639081555316166526932233787566053827355349022396563769697278239577184503627244170930
e2 = 521
n2 = 15944475431088053285580229796309956066521520107276817969079550919586650535459242543036143360865780730044733026945488511390818947440767542658956272380389388112372084760689777141392370253850735307578445988289714647332867935525010482197724228457592150184979819463711753058569520651205113690397003146105972408452854948512223702957303406577348717348753106868356995616116867724764276234391678899662774272419841876652126127684683752880568407605083606688884120054963974930757275913447908185712204577194274834368323239143008887554264746068337709465319106886618643849961551092377843184067217615903229068010117272834602469293571
c2 = 6699274351853330023117840396450375948797682409595670560999898826038378040157859939888021861338431350172193961054314487476965030228381372659733197551597730394275360811462401853988404006922710039053586471244376282019487691307865741621991977539073601368892834227191286663809236586729196876277005838495318639365575638989137572792843310915220039476722684554553337116930323671829220528562573169295901496437858327730504992799753724465760161805820723578087668737581704682158991028502143744445435775458296907671407184921683317371216729214056381292474141668027801600327187443375858394577015394108813273774641427184411887546849
s,s1,s2=gmpy2.gcdext(e1,e2) # s是gcd(e1,e2)=1
m=(pow(c1,s1,n1)*pow(c2,s2,n2)%n1)
print(m)
print(long_to_bytes(m).decode()) # flag{sh4r3_N}

已知:e_{1}*s_{1}+e_{2}*s_{2}=1(根据扩展欧几里得算法)

           c_{1}=m^{e_{1}}\,mod\,n

           c_{2}=m^{e_{2}}\,mod\,n

要证:m=(c_{1}^{s_{1}}\,mod\,n*c_{2}^{s_{2}}\,mod\,n)\,mod\,n

               =>((m^{e_{1}}\,mod\,n)^{s_{1}}\,mod\,n*(m^{e_{2}}\,mod\,n)^{s_{2}}\,mod\,n)\,mod\,n

               =>((m^{e1s1}\,mod\,n)*(m^{e2s2}\,mod\,n))\,mod\,n(根据上面第2节模运算的基本性质中的第4条公式)

               =>(m^{e1s1}*m^{e2s2})\,mod\,n(根据上面第2节模运算的基本性质中的第3条公式)

               =>(m^{e1s1+e2s2})\,mod\,n(同底幂相乘,指数相加)

               =>m^{1}\,mod\,n

               =>m(因为m小于n)

easyrsa4(低加密指数攻击:e很小)

如果e很小,就可以爆破k(m^e=kn+c)

e = 3
n = 18970053728616609366458286067731288749022264959158403758357985915393383117963693827568809925770679353765624810804904382278845526498981422346319417938434861558291366738542079165169736232558687821709937346503480756281489775859439254614472425017554051177725143068122185961552670646275229009531528678548251873421076691650827507829859299300272683223959267661288601619845954466365134077547699819734465321345758416957265682175864227273506250707311775797983409090702086309946790711995796789417222274776215167450093735639202974148778183667502150202265175471213833685988445568819612085268917780718945472573765365588163945754761
c = 150409620528139732054476072280993764527079006992643377862720337847060335153837950368208902491767027770946661
def decrypt(c,e,n):
    k=0
    while 1:
        # c=m^e mod n
        me=k*n+c
        m,t=gmpy2.iroot(me,e) # 对me开e次方,返回两个结果,第1个是结果,第2个结果表示是否完全精确开方(是布尔值)
        if t:
            print(m)
            print(long_to_bytes(m).decode()) # flag{Sm4ll_eee}
            break
        k+=1 # 如果k特别大的话,就会遍历很久
decrypt(c,e,n)

easyrsa5(维纳攻击:e很大)

一般就是用脚本跑(需要将该代码放在rsa-wiener-attack-master目录下)

https://github.com/pablocelayes/rsa-wiener-attack

from Crypto.Util.number import long_to_bytes

from RSAwienerHacker import *
e = 284100478693161642327695712452505468891794410301906465434604643365855064101922252698327584524956955373553355814138784402605517536436009073372339264422522610010012877243630454889127160056358637599704871937659443985644871453345576728414422489075791739731547285138648307770775155312545928721094602949588237119345
n = 468459887279781789188886188573017406548524570309663876064881031936564733341508945283407498306248145591559137207097347130203582813352382018491852922849186827279111555223982032271701972642438224730082216672110316142528108239708171781850491578433309964093293907697072741538649347894863899103340030347858867705231
c = 350429162418561525458539070186062788413426454598897326594935655762503536409897624028778814302849485850451243934994919418665502401195173255808119461832488053305530748068788500746791135053620550583421369214031040191188956888321397450005528879987036183922578645840167009612661903399312419253694928377398939392827

d=hack_RSA(e,n)
m=pow(c,d,n)
print(long_to_bytes(m).decode()) # flag{very_biiiiig_e}

easyrsa6(gmpy2.next_prime)

一般题目会有gmpy2.next_prime这个函数,p和q的值很相近。可以用yafu或在线网站解出p和q,也可以用python脚本解出。

解出p和q后就用公式即可得到flag(0x10001的十进制就是65537)

 方法1:n=p*q开根号得到的结果一定是在p、q之间的的一个数字,那么这个开方出来的数字的下一个素数,一定较大的素数p,再让n//p就可以得到两个素数

temp=gmpy2.iroot(n,2)[0]
p=gmpy2.next_prime(temp)
q=n//p
print(p)
print(q)

方法2:令a是根号n,然后令p=a+b,q=a-b,则n=p*q=(a+b)*(a-b)=a^2-b^2 => b^2=a^2-n。所以在遍历a的时候,求出所有符合条件的b(这个方法不会受到next_prime的限制,如果解不是质数它也会求出解)

a=gmpy2.iroot(n,2)[0]
while 1:
    b2=a**2-n # 令p=a+b,q=a-b,n=p*q=(a+b)*(a-b)=a^2-b^2 => b^2=a^2-n
    a+=1
    if gmpy2.is_square(b2):
        b=gmpy2.iroot(b2,2)[0]
        p=a+b
        q=a-b
        print(p)
        print(q)
        break

easyrsa7(P高位攻击)

 p高位攻击的特征就是看到p>>128<<128且p末尾有很多0

启动sagemath-notebook,运行以下脚本得到p和q,然后就正常套公式解决

from sage.all import *
n = 0x79e0bf9b916e59286163a1006f8cefd4c1b080387a6ddb98a3f3984569a4ebb48b22ac36dff7c98e4ebb90ffdd9c07f53a20946f57634fb01f4489fcfc8e402865e152820f3e2989d4f0b5ef1fb366f212e238881ea1da017f754d7840fc38236edba144674464b661d36cdaf52d1e5e7c3c21770c5461a7c1bc2db712a61d992ebc407738fc095cd8b6b64e7e532187b11bf78a8d3ddf52da6f6a67c7e88bef5563cac1e5ce115f3282d5ff9db02278859f63049d1b934d918f46353fea1651d96b2ddd874ec8f1e4b9d487d8849896d1c21fb64029f0d6f47e560555b009b96bfd558228929a6cdf3fb6d47a956829fb1e638fcc1bdfad4ec2c3590dea1ed3
p4 = 0xd1c520d9798f811e87f4ff406941958bab8fc24b19a32c3ad89b0b73258ed3541e9ca696fd98ce15255264c39ae8c6e8db5ee89993fa44459410d30a0a8af700ae3aee8a9a1d6094f8c757d3b79a8d1147e85be34fb260a970a52826c0a92b46cefb5dfaf2b5a31edf867f8d34d22229
# p4为p去除0的剩余位
# e = 0x10001
pbits = 1024
kbits = pbits - p4.nbits()# 128
print(p4.nbits()) # 896
p4 = p4 << kbits
# print(p4)
PR.<x> = PolynomialRing(Zmod(n))
f = x + p4
roots = f.small_roots(X=2^kbits, beta=0.4)
if roots:        
    p = p4+int(roots[0]) 
    print("n= "+str(n))
    print("p= "+str(p))
    print("q= "+str(n//p))

easyrsa8(利用rsa公钥私钥解题)

使用脚本得到flag

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
public = RSA.importKey(open('public.key').read())
n = public.n
e = public.e
print(n)
print(e)
# 用yafu或在线网站解出p,q
p = 97
q = 106249972159566919549855203174197828387397831115262336234662051342543151219702510584956705611794290291345944183845955839244363030579896461607496959399297130227066841321473005074379950936513608503266587950271044991876848389878395867601515004796212227929894460104645781488319246866661398816686697306692491058609
d=gmpy2.invert(e,(p-1)*(q-1))
rsakey = RSA.importKey(open('public.key','r').read())
privatekey = RSA.construct((n,e,int(d),p,q))
print(privatekey.exportKey()) # 可以生成导出私钥文件
rsa = PKCS1_OAEP.new(privatekey)
m = rsa.decrypt(open('flag.enc','rb').read())
# rsa=PKCS1_v1_5.new(privatekey)
# m = rsa.decrypt(open('flag.enc','rb').read(),0) # 两种填充方式
print(m.decode()) # flag{p_1s_5mall_num6er}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值