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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

一文搞懂RSA算法原理及简单实现

發(fā)布時(shí)間:2024/4/15 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一文搞懂RSA算法原理及简单实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

RSA算法是最重要的算法之一,它是一種非對(duì)稱加密,是目前最有影響力的加密方式之一。這篇文章我們通過實(shí)現(xiàn)一種簡(jiǎn)單的RSA加密來探究它的原理。

計(jì)算公鑰和私鑰

RSA中的公鑰和私鑰需要結(jié)合在一起工作。公鑰用來對(duì)數(shù)據(jù)塊加密,之后 ,只有對(duì)應(yīng)的私鑰才能用來解密。生成密鑰時(shí),需要遵循幾個(gè)步驟以確保公鑰和私鑰的這種關(guān)系能夠正常工作。這些步驟也確保沒有實(shí)際方法能夠從一個(gè)密鑰推出另一個(gè)。

開始前,首先要選擇兩個(gè)大的素?cái)?shù),記為p和q。根據(jù)當(dāng)今求解大數(shù)因子的技術(shù)水平,這兩個(gè)數(shù)應(yīng)該至少有200位,這們?cè)趯?shí)踐中才可以認(rèn)為是安全的。

然后,開始計(jì)算n:

n = pq

接下來,選擇一個(gè)小的奇數(shù)e,它將成為公鑰的一部分。選擇e最需要考慮的重點(diǎn)是它與(p-1)(q-1)不能有相同的因子。換句話說,e與(p-1)(q-1)是互為素?cái)?shù)關(guān)系的。比如,如果p=11而q=19,那么n=11 X 19=209。這里選擇e=17,因?yàn)?p-1)(q-1)=10 X 18 =180,而17和180沒有相同的因子。通常選擇3、17、65、537作為e的值。使用這些值不會(huì)對(duì)RSA的安全性造成影響,因?yàn)榻饷軘?shù)據(jù)還需要用到私鑰。

一旦為e選擇了一個(gè)值,接下來開始計(jì)算相對(duì)應(yīng)的值d,d將成為私鑰的一部分。d的值就是計(jì)算e的倒數(shù)對(duì)(p-1)(q-1)的取模結(jié)果,公式如下:

d = e-1 mod (p-1)(q-1)

這里d和e是模乘法逆元的關(guān)系。

思考一下這個(gè)問題:當(dāng)d為多少時(shí)可以滿足ed mod (p-1)(q-1) = 1 ?比如在等式 17d mod 180 = 1中,d的一個(gè)可能值是53。其他的可能值是233、413、593等。在實(shí)踐中,可以利用歐幾里德算法來計(jì)算模乘法逆元。這里就不再展開。

現(xiàn)在有了e和d的值,將(e,n)作為公鑰P,將(d,n)作為私鑰S并保持其不可見。

如何計(jì)算d?

上面p、q、e需要預(yù)設(shè)三個(gè)素?cái)?shù),n很容易求出來,但是d的計(jì)算就涉及到模的運(yùn)算了

什么是模、取模和模運(yùn)算?

取模:
https://baike.baidu.com/item/%E5%8F%96%E6%A8%A1%E8%BF%90%E7%AE%97/10739384?fr=aladdin

模運(yùn)算:
https://baike.baidu.com/item/%E6%A8%A1%E8%BF%90%E7%AE%97/4376110

具體就不細(xì)說了,但是要注意取模和取余的區(qū)別

這里d = e-1 mod (p-1)(q-1)

簡(jiǎn)化為:

d = e-1 % m

這是乘法逆元的問題。我們對(duì)上面的進(jìn)行處理

d * e = e-1 % m * e

(d * e) % m = (e-1 % m * e) %m

根據(jù)模運(yùn)算的結(jié)合率
(a%p * b)%p=(a * b)%p

(d * e) % m = (e-1 % m * e) %m = (e-1 * e) % m = 1 % m

所以我們最后得到

(d * e) % m = 1 % m

這里由于n說我們自己定義的,一定是正數(shù),所以1%n=1

所以最后變?yōu)橛?jì)算

(d * e) % m = 1

并且e和d一定有一組解滿足他們都小于m。我們只需求這組解即可。

根據(jù)費(fèi)馬小定理,如果a和b互質(zhì),則

ab-1 % b = 1

那么已經(jīng)要求e與m互質(zhì),所以

(e * em-2) % m = 1

所以d的一個(gè)解是em-2,但是這個(gè)很可能比m大,則可以表示為m + k,那么

(e * (m + k)) % m = 1

根據(jù)模的加法運(yùn)算規(guī)則

(em % m + e*k % m) % m = 1

因?yàn)閑m % m一定是0,所以上面的可以轉(zhuǎn)為

e*k % m = 1

如果k還大于m,則重復(fù)上面的步驟直到k小于m。這時(shí)k就是d。

因?yàn)閑小于m,所以d一定有一個(gè)小于m的解使 (d * e) % m = 1成立

代碼

簡(jiǎn)單的算法是遍歷找到d,代碼:

var q = 13; var p = 17; var n = q * p; var e = 7; var tmp = (q - 1) * (p - 1); var d; for (d = 1; ; d++) {if (e * d % tmp === 1) {break} }

這里還需要進(jìn)行優(yōu)化,因?yàn)橐话鉵都是超大數(shù),而e則比較小,所以d也會(huì)很大,這里就需要大量的循環(huán),優(yōu)化后如下:

var d;for (var j = 1; j < e; j++) {if ((tmp * j + 1) % e === 0) {d = (tmp * j + 1) / e;break;}}

因?yàn)?(d * e) % m = 1也就是

d * e = k * m + 1

而且d也需要小于m,所以k一定小于e,而e是比較小的值,所以我們將循環(huán)改成k即可減少大量的計(jì)算。

加密和解密數(shù)據(jù)分組

要使用RSA算法對(duì)數(shù)據(jù)進(jìn)行加密和解密,首先要確定分組的大小。為了實(shí)現(xiàn)這一步,必須確保該分組可以保存的最大數(shù)值要小于n的位數(shù)。比如,如果p和q都是200位數(shù)字的素?cái)?shù),則n的結(jié)果將小于400位。因而,所選擇的分組所能保存的最大值應(yīng)該要以是接近于400。在實(shí)踐中,通常選擇的位數(shù)都是比n小的2的整數(shù)次冪。比如,如果n是209,要選擇的分組大小就是7位,因?yàn)?7 = 128比209小,但28 = 256又大于209。

要從緩沖區(qū)M中加密第(i)組明文Mi ,使用公鑰(e,n)來獲取M的數(shù)值,對(duì)其求e次冪,然后再對(duì)n取模。這將產(chǎn)生一組密文Ci。對(duì)n的取模操作確保了Ci將和明文的分組大小保持一致。因而,要加密明文分組有:

Ci = Mie mod n

之前提到過,歐拉函數(shù)是采用冪模運(yùn)算來加密數(shù)據(jù)的基礎(chǔ),根據(jù)歐拉函數(shù)及其推導(dǎo)式,能夠?qū)⒚芪慕饷芑卦摹?/p>

要對(duì)緩沖區(qū)中C中的第(i)組密文進(jìn)行解密,使用私鑰(d,n)來獲取Ci的數(shù)值部分,對(duì)其求d次冪,然后再對(duì)n取模。這將產(chǎn)生一組明文Mi。因此,要解密密文分組有:

Mi = Cid mod n

計(jì)算過程及優(yōu)化

這里加密解密的算法一樣,只不過key值不同而已,涉及的是模的冪運(yùn)算

以加密為例

Ci = Mie mod n

因?yàn)樾枰紤]大數(shù)的問題,所以模的冪運(yùn)算不能直接運(yùn)算,比如如果我先直接計(jì)算Mie,由于Mi有可能是很大的數(shù),這樣它的e次冪就會(huì)是一個(gè)超級(jí)數(shù)字,計(jì)算機(jī)無法計(jì)算和存儲(chǔ)

所以這里我們就需要對(duì)模冪運(yùn)算進(jìn)行優(yōu)化,就涉及到了蒙哥馬利算法

參考
https://blog.csdn.net/zgzczzw/article/details/52712980
https://blog.csdn.net/linraise/article/details/17490769)

蒙哥馬利算法比較復(fù)雜,包含三個(gè)算法進(jìn)行優(yōu)化。

我們先設(shè)計(jì)一個(gè)簡(jiǎn)單的算法,先將模冪運(yùn)算轉(zhuǎn)化為模乘運(yùn)算

關(guān)于模運(yùn)算,有如下幾個(gè)公式:

結(jié)合律(a%p*b)%p=(a*b)%p同理((a*b) % p * c)% p = (a*b*c) % p 四則運(yùn)算(a * b) % p = (a % p * b % p) % p (a^b) % p = ((a % p)^b) % p

我們先利用上面兩個(gè)結(jié)合律,所以:

a2%n = (a * a) %n = (a%n * a) %n

因?yàn)閍%n取模一定比a小,所以a%n*a就要比a2小很多,類推

a3%n = (a2 * a) %n = ((a2%n)*a)%n

得出

an%n = ((an-1%n)*a)%n

這是一個(gè)簡(jiǎn)單遞歸算法,通過這個(gè)算法,每次乘完都會(huì)做一個(gè)取模運(yùn)算,運(yùn)算的數(shù)據(jù)就會(huì)小很多。

代碼:

function encode(x, e, n) {var result = x % n;for (var i = 1; i < e ; i++) {result = (result * x) % n;}return result }function decode(x, d, n) {var result = x % n;for (var i = 1; i < d ; i++) {result = (result * x) % n;}return result }

當(dāng)然,上面僅僅是簡(jiǎn)單例子,因?yàn)槿绻麅鐢?shù)較大比如d就會(huì)是一個(gè)超大數(shù),這樣循環(huán)次數(shù)就會(huì)很多,計(jì)算時(shí)間很長(zhǎng)。

根據(jù)模的運(yùn)算法則:

(a % p * b) % p = (a * b) % p

(a * b) % p = (a % p * b % p) % p

我們可以得出,當(dāng)指數(shù)(假設(shè)為e)是偶數(shù)時(shí)

se % n = ((se/2 % n) * (se/2 % n)) % n

當(dāng)為奇數(shù)時(shí)則可以先轉(zhuǎn)成偶數(shù)

se % n = ((se - 1 % n) * e) % n

這樣就可以用二分法和位運(yùn)算來優(yōu)化算法。如下:

function modpow(x, p, m) {if(p === 1){return mod(x, m)}var mid;if((p & 1) === 0){mid = (p >> 1);var tmp1 = modpow(x, mid, m);return mod(tmp1 * tmp1, m);}else{return mod(modpow(x, p - 1, m) * x, m)} }

1、利用遞歸二分。因?yàn)殚_方所以每個(gè)節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn)都相等,所以計(jì)算其中一個(gè)就可以,這樣我們只需計(jì)算二叉樹的一條路徑就可以了,整體復(fù)雜度只有O(log2n)。比如2n只需要計(jì)算n + x次(最多壞情況每次都是奇數(shù)則是2n),比2n次計(jì)算節(jié)省大量的時(shí)間,而且數(shù)據(jù)越大節(jié)省時(shí)間越多。

2、位運(yùn)算。在判斷奇偶數(shù)時(shí),沒有使用除法,因?yàn)槌ㄟ\(yùn)算復(fù)雜度很大,耗時(shí)比其他運(yùn)算長(zhǎng)很多。這里使用位運(yùn)算,只需判斷最低位是否為0即可,而除2運(yùn)算則可以用右移一位代替。因?yàn)橛?jì)算機(jī)中位運(yùn)算最快,所以這樣會(huì)節(jié)省大量的時(shí)間。

正確性驗(yàn)證

加密我們可以理解,因?yàn)檫\(yùn)算中有模參與,所以不可逆。但是加密后為什么通過私鑰就可以解密,解密一定正確么?

首先加密

k = se % n

然后對(duì)k解密

r = ((se % n)d) %n

根據(jù)(a^b) % p = ((a % p)^b) % p可得

r = (se)d % n = se*d % n

通過之前的計(jì)算可知 (d * e) % m = 1,而m是(q-1)(p-1),所以

d * e = k(q-1)(p-1) + 1 (k未知)

而且n=pq,所以

r = sk(q-1)(p-1) + 1 % (pq)

根據(jù)費(fèi)馬小定理,如果a和b互質(zhì),則

ab-1 = 1 mod b

所以考慮兩種情況:

1、s與n即pq互質(zhì)

因?yàn)閜和q是兩個(gè)大質(zhì)數(shù),所以s與n互質(zhì)就相當(dāng)于s分別于p和q互質(zhì)

所以根據(jù)費(fèi)馬小定理

sp-1 = 1 mod p

sp-1 % p = 1

所以根據(jù)冪模的運(yùn)算法則(a^b) % p = ((a % p)^b) % p

sk(q-1)(p-1) % p = (sp-1 % p)k(q-1) % p

因?yàn)閟p-1 % p = 1,所以

sk(q-1)(p-1) % p = 1k(q-1) % p = 1

同理可以得出

sk(q-1)(p-1) % q = 1

所以sk(q-1)(p-1) - 1可以被p和q都整除,得出

sk(q-1)(p-1) % (pq) = 1

回到之前

r = sk(q-1)(p-1) + 1 % (pq) = (sk(q-1)(p-1) * s) % (pq)

根據(jù)模的結(jié)合率(a%p * b)%p=(a * b)%p

r = ( (sk(q-1)(p-1) % (pq)) * s ) % (pq)

上面推出sk(q-1)(p-1) % (pq) = 1,所以

r = s % (pq)

因?yàn)閜q = n所以最終

r = s % n

根據(jù)上面RSA算法要求,可知s一定是小于n的數(shù),所以s對(duì)n取模結(jié)果也是s

所以 r = s 驗(yàn)證了RSA的正確性。

2、s于n不互質(zhì)

總結(jié)

以上是生活随笔為你收集整理的一文搞懂RSA算法原理及简单实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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