RSA密碼的學習以及幾種常見CTF題型的總結(收集RSA解題腳本)


放在最前面

大師傅博客
從數盲到口算 ——帶你玩轉RSA加密算法(一)
你想要的RSA解題技巧(二)
前言:gmpy2庫終於安裝好了,那就能開心的玩耍了。
一個平台一個平台的“掃盪”
RSA這類題真是每次看見都着急,學腳本吧?但是又沒有gmpy2。無奈,現在終於有了,我要把之前每寫出來的題掃一遍。
關於RSA的這個密碼。數學邏輯比較……那啥一點,跟着B站上的一個up主學的,講的挺好,聽着聽着睡着了。讓我找到了高中的感覺。跑題了,,咳咳。當然還有師傅們的博客提供學習幫助。

RSA密碼原理

來自漏斗社區
數學知識:
首先:取模運算知識,就是取余數。可以使用python的pow函數來解
pow的解法如下:

Augenstern
其次:同余運算。兩個整數a,b,它們除以整數M所得的余數相等:a ≡ b(mod m),比如說5除3余數為2,11除3余數也為2,於是可寫成11 ≡ 5(mod 3)。
RSA加密算法:
一個原理圖,從漏斗社區借鑒的
來自漏斗社區
來自漏斗社區
這兩張圖對於理解rsa加密很有幫助,我從這兩張圖中理解后思路變的更清晰了。
還有一張解析CTF中的rsa基礎題型的圖。聲明:是漏斗社區的師傅寫的,我只是搬過來做個筆記,方便以后查詢使用。
來自漏斗社區
做幾個類型的題目記錄一下,防止以后忘記方便復習。

BUUCTF

RSA

Augenstern
這道題是一種類型,已知p,q,e,求d
可以用求d的腳本直接解出,運行腳本需要用到gmpy2第三方庫。
直接上腳本

#!------Augenstern------!
#!lalalalalala------lalalalalalalalala!
#!***********lxj python***********!
import gmpy2
from Crypto.Util import number
p = 473398607161
q = 4511491
e = 17
d = gmpy2.invert(e,(p-1)*(q-1))
print (d)

flag{125631357777427553}

rsarsa

Augenstern
腳本關。

import gmpy2
def Decrypt(c,e,p,q):
	L=(p-1)*(q-1)
	d=gmpy2.invert(e,L)
	n=p*q
	m=gmpy2.powmod(c,d,n)
	flag=str(m)
	print("flag{"+flag+"}")
if __name__ == '__main__':
	p =  9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
	q =  11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
	e =  65537
	c =  83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034
	Decrypt(c,e,p,q)

注釋:
__name__=='__main__'一個python文件通常有兩種使用方法,
第一是作為腳本直接執行,
第二是 import 到其他的 python 腳本中被調用(模塊重用)執行。因此 if __name__ == 'main': 的作用就是控制這兩種情況執行代碼的過程,在 if __name__ == 'main': 下的代碼只有在第一種情況下(即文件作為腳本直接執行)才會被執行,而 import 到其他腳本中是不會被執行的,忘了就再看看大佬的博客大佬博客
flag其他沒什么了。flag直接得到。

RSA1

Augenstern
其實通過這道題我學到很多,一點一點看

dp=d%(p-1)
dq=d%(q-1)

這個腳本不會寫,我只會寫那種異常的簡單的小腳本,這種不會寫。本人臉皮厚當個script boy。😪😪

import gmpy2
import libnum
def decrypt(dp,dq,p,q,c):
    InvQ = gmpy2.invert(q, p)
    mp = pow(c, dp, p)
    mq = pow(c, dq, q)
    m = (((mp-mq)*InvQ) % p)*q+mq
    print (libnum.n2s(m))

p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229 
q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469 
dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929 
dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041 
c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852
decrypt(dp,dq,p,q,c)

結果得到:
Augenstern

RSA2

Augenstern
知道dp,n,e;求明文m.,我還是不會寫腳本,現在才發現我這篇博客就是用來收集腳本的。

import gmpy2 as gp

e = 65537
n = gp.mpz(248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113)
dp = gp.mpz(905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657)

c = gp.mpz(140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751)

for x in range(1, e):
    if(e*dp%x==1):
        p=(e*dp-1)//x+1
        if(n%p!=0):
            continue
        q=n//p
        phin=(p-1)*(q-1)
        d=gp.invert(e, phin)
        m=gp.powmod(c, d, n)
        if(len(hex(m)[2:])%2==1):
            continue
        print('--------------')
        print(m)
        print(hex(m)[2:])
        print(bytes.fromhex(hex(m)[2:]))

結果:
Augenstern

RSA3

Augenstern
已知c1、c2、e1、e1、n 的情況

from gmpy2 import *
import libnum

n=22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
e1=11187289
e2=9647291
s = gcdext(e1, e2)
s1 = s[1]
s2 = -s[2]

c1=22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
c2=18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
e2=9647291
c2 = invert(c2, n)
m = (pow(c1,s1,n) * pow(c2 , s2 , n)) % n
print (m)
print (libnum.n2s(m))

結果:
Augenstern

RSA

Augenstern
打開壓縮包,是兩個文件
Augenstern
打開這個文件(txt打開或者notepad++)
發現了公鑰
Augenstern
在線解析公鑰的網站直接解析出我們需要的信息在線解析公鑰
Augenstern
得到n和e
分解n得到p和q ,可以使用yafu因數分解大數
Augenstern
也可以在線網站分解,這個還不算大數,如果特別大的數還是yafu 比較好用啦。
Augenstern
最后都能得出結果來
腳本:

import gmpy2
import rsa

p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463
e = 65537
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517

d = gmpy2.invert(e,(q-1)*(p-1))
print(d)

d = 81176168860169991027846870170527607562179635470395365333547868786951080991441

key = rsa.PrivateKey(n,e,d,p,q)
print(key)

with open("flag.enc","rb") as f:
	print(rsa.decrypt(f.read(),key).decode())

運行結果:
Augenstern
過程中遇到的錯誤:
原本我是在pycharm里跑腳本,但是跑這個腳本的時候 報錯了。報錯信息是這樣的。
AttributeError: module 'rsa' has no attribute 'PrivateKey'
Augenstern
這種報錯毫無頭緒,百度找不到類似的錯誤,然后我懷疑腳本的問題,然后又找找其他的腳本,但是發現報錯信息差不多,都是這個地方。想起來我電腦上還安裝了ipython,於是就試試,但是也跑不出來。就去問了問學長。學長說在kali里面試試。這個我還沒試,因為那里面還沒安裝gmpy2這個庫。明天再安裝。這期間我發現錯誤就是路徑的問題。倒數第二行代碼,打開文件flag.enc這個文件,要添加路徑,路徑中原本的\在這里使用\\因為轉義。我於是又在pycharm里跑了一次,但是沒有結果,同樣的錯誤。
重點:我在ipython中試了一下,結果驚喜來了,成功了。就得到了上面的運行結果。
回頭kali安裝好gmpy2這個庫之后我再試試這個題。
我還以為這篇博客真的要成為一篇純粹收集腳本的文章了呢。還是有自己的收獲的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM