日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【笔记】公钥密码学之RSA

發(fā)布時(shí)間:2025/3/21 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【笔记】公钥密码学之RSA 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

數(shù)論基礎(chǔ)

素?cái)?shù)

1.定義: 一個(gè)大于1的自然數(shù),除了1和它本身外,不能被其他自然數(shù)整除(除0以外)的數(shù)稱之為素?cái)?shù)(質(zhì)數(shù));否則稱為合數(shù)。

如:3×4 = 12,不是素?cái)?shù)。11除了等于11×1以外,不能表示為其它任何兩個(gè)整數(shù)的乘積,所以11是一個(gè)素?cái)?shù)。

2.關(guān)于素?cái)?shù)的事實(shí):

(1)如果p是素?cái)?shù),且p | ab(表示ab能被p整除),則p | a或 p | b ,即p 至少整除a與b中的一個(gè)。

(2)算術(shù)基本定理:任何一個(gè)大于1的自然數(shù) ,如果N不為質(zhì)數(shù),都可以唯一分解成有限個(gè)質(zhì)數(shù)的乘積,即

(3)素?cái)?shù)有無窮多個(gè)。

最大公約數(shù)與最小公倍數(shù)

1.最大公約數(shù)

定義:幾個(gè)數(shù)公有的約數(shù),叫做這幾個(gè)數(shù)的公約數(shù),其中最大的一個(gè)叫做這幾個(gè)數(shù)的最大公約數(shù)。數(shù)學(xué)上,a和b的最大公約數(shù)記為(a, b),編程中,計(jì)算兩個(gè)數(shù)最大公約數(shù)的方法通常記為gcd(a,b)

2.最小公倍數(shù)

定義:幾個(gè)數(shù)公有的倍數(shù),叫做這幾個(gè)數(shù)的公倍數(shù),其中最小的一個(gè)叫做這幾個(gè)數(shù)的最小公倍數(shù)。數(shù)學(xué)上,a和b的最小公倍數(shù)記為[a,b],編程中,計(jì)算兩個(gè)數(shù)最小公倍數(shù)的方法通常記為lcm(a,b)

歐拉函數(shù)

1.定義: 在數(shù)論中,對正整數(shù)n,歐拉函數(shù)φ(n)是小于或等于n的正整數(shù)中與n互質(zhì)的數(shù)的數(shù)目。此函數(shù)以其首名研究者歐拉命名,它又稱為φ函數(shù)(由高斯所命名)或是歐拉總計(jì)函數(shù)。例如:φ(8) = 4 ,因?yàn)?,3,5,7均與8互質(zhì)。

2.性質(zhì):

歐拉函數(shù)是積性函數(shù)——若m,n互質(zhì),φ(mn)=φ(m)φ(n)

特殊性質(zhì):當(dāng)n為奇數(shù)時(shí),φ(2n)=φ(n)

歐幾里得(Euclid)算法

1.定義: 歐幾里得算法又稱為輾轉(zhuǎn)相除法,用于求兩個(gè)數(shù)的最大公約數(shù)。基于如下原理:兩個(gè)整數(shù)的最大公約數(shù)等于其中較小的數(shù)和兩數(shù)相除余數(shù)的最大公約數(shù),即GCD(x,y) = GCD(y,x mod y) ,x>y。

2.代碼實(shí)現(xiàn):

def GCD(x, y):|if(y==0):return xelse:return GCD(y,x %y) from gmpy2 import* m = gcd(a,b) #from Crypto.Util. number import* #m = GCD(a, b)

擴(kuò)展歐幾里得算法

1.定理: 擴(kuò)展歐幾里德算法是歐幾里得算法的擴(kuò)展。若a和b為正整數(shù),則存在整數(shù)x,y使得gcd(a,b)=ax+by;換句話說gcd(a,b)可以表示為a,b的整洗數(shù)線性組合。
例如:gcd(6,14)=2,而2=(-2)* 6+1 *14.

2.代碼實(shí)現(xiàn):

from gmpy2 import* x=17 y = 65537 #擴(kuò)展歐幾里得算法 s = gcdext(x,y) #返回元組tuple,滿足s[1]*x+s[2]*y = 1 print(s) #輸出: (mpz(1), mpz(30841), mpz(-8)) print(s[1]*x+s[2]*y) #輸出: 1

同余

1.定義: 設(shè)a,b是整數(shù),n≠0,如果n|(a-b),則稱a和b模n同余,記為a≡b(mod n),整數(shù)n稱為模數(shù)。由于n|(a-b) 等價(jià)于 -n|(a-b),所以a≡b(mod n) 與 a≡b(mod (-n))等價(jià)。因此,一般我們總假定模數(shù)n≥1。

2.性質(zhì)1:

(1)自反性:a ≡ a (mod m)

(2)對稱性:a ≡ b (mod m),?b ≡ c (mod m) ?a ≡ c (mod m)

(3)保持基本運(yùn)算:

模運(yùn)算

1.定義: a模n的運(yùn)算給出了a對模n的余數(shù),這種運(yùn)算稱為模運(yùn)算。注意:模運(yùn)算的結(jié)果是從0到n-1的一個(gè)整數(shù)。

2.性質(zhì): 模運(yùn)算就像普通的運(yùn)算一樣,它是可交換、可結(jié)合、可分配的。而且,對每一個(gè)中間結(jié)果進(jìn)行模m運(yùn)算后再進(jìn)行模m運(yùn)算,其作用與先進(jìn)行全部運(yùn)算,然后再進(jìn)行模m運(yùn)算所得到的結(jié)果是一樣的。

(a+b)mod m=((a mod m)+(b mod m)) mod m

(a-b)mod m=((a mod m)-(b mod m)) mod m

(a×b)mod m=((a mod m) ×(b mod m)) mod m

(a×(b+c))mod m=((a×b) mod m+(a×c) mod m) mod m

3.用途:

(1)用于判斷一個(gè)數(shù)是否能被另一個(gè)數(shù)整除。對 2 取模即可判斷整數(shù)的奇偶性;從 2 到 n-1 取模則可判斷一個(gè)數(shù)是否為質(zhì)數(shù)。
(2)進(jìn)制之間的轉(zhuǎn)換。
(3)用于求取最大公約數(shù)的輾轉(zhuǎn)相除法使用取模運(yùn)算。
(4)密碼學(xué)中的應(yīng)用:從古老的凱撒密碼到現(xiàn)代常用的RSA、橢圓曲線密碼,它們的實(shí)現(xiàn)過程均使用了取模運(yùn)算。

模逆元

1.定義: 模逆元也稱為模倒數(shù),或者模逆元。

一整數(shù)a對同余n之模逆元是指滿足以下公式的整數(shù) b

2.求解方法:

(1)擴(kuò)展歐幾里得算法:設(shè)exgcd(a,n)為擴(kuò)展歐幾里得算法的函數(shù),則可得到ax+ny=g,g是a,n的最大公因數(shù)。若g=1,則該模逆元存在;若g≠1,則該模逆元不存在。

(2)歐拉定理:歐拉定理證明當(dāng)a,n為兩個(gè)互素的正整數(shù)時(shí),則有aφ(n)≡1(modn),φ(n)為歐拉函數(shù),其中 aφ(n)-1即為a關(guān)于模n之模逆元

中國剩余定理

中國剩余定理給出了以下的一元線性同余方程組有解的判定條件,并用構(gòu)造法給出了在有解情況下解的具體形式。

中國剩余定理說明:假設(shè)整數(shù)m1, m2, … , mn其中任兩數(shù)互質(zhì),則對任意的整數(shù):a1, a2, … , an,上述一元線性同余方程組有解,并且通解可以用如下方式構(gòu)造得到:

RSA算法

RSA算法簡介

RSA攻擊方法

思維導(dǎo)圖

常見題型

1.模數(shù)分解

題目鏈接(buu平臺(tái))

from flag import FLAG from Cryptodome.Util.number import * import gmpy2 import randome=65537 p = getPrime(512) q = int(gmpy2.next_prime(p)) n = p*q m = bytes_to_long(FLAG) c = pow(m,e,n) print(n) print(c) # n=177606504836499246970959030226871608885969321778211051080524634084516973331441644993898029573612290095853069264036530459253652875586267946877831055147546910227100566496658148381834683037366134553848011903251252726474047661274223137727688689535823533046778793131902143444408735610821167838717488859902242863683 # c=1457390378511382354771000540945361168984775052693073641682375071407490851289703070905749525830483035988737117653971428424612332020925926617395558868160380601912498299922825914229510166957910451841730028919883807634489834128830801407228447221775264711349928156290102782374379406719292116047581560530382210049

題目為最基礎(chǔ)的RSA加密,其中p q為相鄰的素?cái)?shù)。可以用yafu分解


基礎(chǔ)RSA解密:

n=177606504836499246970959030226871608885969321778211051080524634084516973331441644993898029573612290095853069264036530459253652875586267946877831055147546910227100566496658148381834683037366134553848011903251252726474047661274223137727688689535823533046778793131902143444408735610821167838717488859902242863683 c=1457390378511382354771000540945361168984775052693073641682375071407490851289703070905749525830483035988737117653971428424612332020925926617395558868160380601912498299922825914229510166957910451841730028919883807634489834128830801407228447221775264711349928156290102782374379406719292116047581560530382210049 e=65537 p = 13326909050357447643526585836833969378078147057723054701432842192988717649385731430095055622303549577233495793715580004801634268505725255565021519817179293 q = 13326909050357447643526585836833969378078147057723054701432842192988717649385731430095055622303549577233495793715580004801634268505725255565021519817179231 from Crypto.Util.number import * phi=(p-1)*(q-1) d=inverse(e,phi) m=pow(c,d,n) print(long_to_bytes(m)) # actf{p_and_q_should_not_be_so_close_in_value}

2.n有相同的質(zhì)因數(shù)

題目鏈接(buu平臺(tái))

題面:一份秘密發(fā)送給兩個(gè)人不太好吧,那我各自加密一次好啦~~~
素?cái)?shù)生成好慢呀
偷個(gè)懶也……不會(huì)有問題的吧?

附件:
public1.pub
public2.pub
flag_encry1
flag_encry2

首先嘗試取出兩份公鑰文件的n,e,測試發(fā)現(xiàn)n1 n2有公約數(shù),正好印證了題面給的懶得生成素?cái)?shù),所以共用了其中一個(gè)素?cái)?shù)。

求解公約數(shù)即可:

from Crypto.PublicKey import RSA import gmpy2 from Crypto.Util.number import * f=open("public1.pub","r") rsa1=RSA.import_key(f.read()) n1=rsa1.n e1=rsa1.e f.close() f=open("public2.pub","r") rsa2=RSA.import_key(f.read()) n2=rsa2.n e2=rsa2.e f.close() #print(n1,e1) #print(n2,e2) p=gmpy2.gcd(n1,n2) q=n2//p assert(p*q==n2) phi=(p-1)*(q-1) d=gmpy2.invert(e2,phi) c_bytes=open("flag_encry2","rb").read() c=bytes_to_long(c_bytes) m=pow(c,d,n2) print(long_to_bytes(m)) #afctf{You_Know_0p3u55I}

3.共模攻擊

題目鏈接(BUU平臺(tái))

hint.py如下:

from gmpy2 import * from Crypto.Util.number import * from secret import hintm = bytes_to_long(hint) p = getPrime(256) c = pow(m, 256, p) print(p)p, q = getPrime(256), getPrime(256) n = p * q e1, e2 = getPrime(32), getPrime(32) c1, c2 = pow(c, e1, n), pow(c, e2, n) print(n) print(e1, c1) print(e2, c2)''' 107316975771284342108362954945096489708900302633734520943905283655283318535709 6807492006219935335233722232024809784434293293172317282814978688931711423939629682224374870233587969960713638310068784415474535033780772766171320461281579 2303413961 1754421169036191391717309256938035960912941109206872374826444526733030696056821731708193270151759843780894750696642659795452787547355043345348714129217723 2622163991 1613454015951555289711148366977297613624544025937559371784736059448454437652633847111272619248126613500028992813732842041018588707201458398726700828844249 '''

task.py如下:

from gmpy2 import * from Crypto.Util.number import * from secret import flagflag = flag.strip(b"npuctf{").strip(b"}") m = bytes_to_long(flag)p, q = getPrime(512), getPrime(512) n = p * q e1, e2 = p, q c1, c2 = pow(m, e1, n), pow(m, e2, n)print(n) print(c1) print(c2)''' 128205304743751985889679351195836799434324346996129753896234917982647254577214018524580290192396070591032007818847697193260130051396080104704981594190602854241936777324431673564677900773992273463534717009587530152480725448774018550562603894883079711995434332008363470321069097619786793617099517770260029108149 96860654235275202217368130195089839608037558388884522737500611121271571335123981588807994043800468529002147570655597610639680977780779494880330669466389788497046710319213376228391138021976388925171307760030058456934898771589435836261317283743951614505136840364638706914424433566782044926111639955612412134198 9566853166416448316408476072940703716510748416699965603380497338943730666656667456274146023583837768495637484138572090891246105018219222267465595710692705776272469703739932909158740030049375350999465338363044226512016686534246611049299981674236577960786526527933966681954486377462298197949323271904405241585 '''

共模攻擊,用擴(kuò)展歐幾里得算法求出c。

原理:當(dāng)GCD(e1, e2) == 1時(shí),由擴(kuò)展歐幾里得算法得,存在s1, s2使 e1s1 + e2s2 = 1,m = pow(m, e1s1 + e2s2, n),而pow(m, e1s1 + e2s2, n) = pow(m, e1s1, n) * pow(m, e2s2, n) = pow(c1, s1, n) * pow(c2, s2, n)

由c和p可以求得m。得到c后,根據(jù)表達(dá)式:c = m256 mod p,可以借助Python的sympy庫nthroot_mod方法,最終由m得到hint:# m =“m.bit_length() < 400”

from gmpy2 import* from sympy import* from Crypto.Util.number import * p = 107316975771284342108362954945096489708900302633734520943905283655283318535709e1 = 2303413961 c1 = 1754421169036191391717309256938035960912941109206872374826444526733030696056821731708193270151759843780894750696642659795452787547355043345348714129217723e2 = 2622163991 c2 = 1613454015951555289711148366977297613624544025937559371784736059448454437652633847111272619248126613500028992813732842041018588707201458398726700828844249 n = 6807492006219935335233722232024809784434293293172317282814978688931711423939629682224374870233587969960713638310068784415474535033780772766171320461281579s = gcdext(e1,e2) c = pow(c1,s[1],n)*pow(c2,s[2],n) % n print(c) #c = 19384002358725759679198917686763310349050988223627625096050800369760484237557m = nthroot_mod(c,256,p) print(long_to_bytes(m))# m ="m.bit_length() < 400"

參考博客
求m:

from Crypto.Util.number import*n = 128205304743751985889679351195836799434324346996129753896234917982647254577214018524580290192396070591032007818847697193260130051396080104704981594190602854241936777324431673564677900773992273463534717009587530152480725448774018550562603894883079711995434332008363470321069097619786793617099517770260029108149 c1 = 96860654235275202217368130195089839608037558388884522737500611121271571335123981588807994043800468529002147570655597610639680977780779494880330669466389788497046710319213376228391138021976388925171307760030058456934898771589435836261317283743951614505136840364638706914424433566782044926111639955612412134198 c2 = 9566853166416448316408476072940703716510748416699965603380497338943730666656667456274146023583837768495637484138572090891246105018219222267465595710692705776272469703739932909158740030049375350999465338363044226512016686534246611049299981674236577960786526527933966681954486377462298197949323271904405241585a = c1+c2 b = c1*c2print(a) print(b)# a = 106427507401691650533776606268030543324548306805584488340881108460215302001780649045082140067384306297497785054794169701530927082798998717147796265177082494273319180022953309137549878052025764276170773098393102683446915458123682447310617265418188192465923366892572673596378919944244343124060963227516817375783 # b = 926651656671911333597022401968870409343942400492881255142377951759176631494915016941991504123810265329862246592861145719213675502795378053564904818765377025096483601036025012267103260702787555612216755188521913405305861451125814149409508425602231670292131422273268728629782633354498648021859614223672123489318899205627785426402597996319440198218774038390809403281952702730883306007226797632389267386912707857093556335846269954270572920361347019614365402744026533713442449916555425678184406380167614011131702418493073759816310890056281917310110034453007210415242707924141697749818907383248545179118594511927630223830flag = 4242839043019782000788118887372132807371568279472499477998758466224002905442227156537788110520335652385855 print(long_to_bytes(flag)) # verrrrrrry_345yyyyyyy_rsaaaaaaa_righttttttt?

總結(jié)

以上是生活随笔為你收集整理的【笔记】公钥密码学之RSA的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。