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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

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

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

前言

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

計算公鑰和私鑰

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

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

然后,開始計算n:

n = pq

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

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

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

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

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

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

如何計算d?

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

什么是模、取模和模運算?

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

模運算:
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)

簡化為:

d = e-1 % m

這是乘法逆元的問題。我們對上面的進行處理

d * e = e-1 % m * e

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

根據(jù)模運算的結(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)橛嬎?/p>

(d * e) % m = 1

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

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

ab-1 % b = 1

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

(e * em-2) % m = 1

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

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

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

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

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

e*k % m = 1

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

因為e小于m,所以d一定有一個小于m的解使 (d * e) % m = 1成立

代碼

簡單的算法是遍歷找到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} }

這里還需要進行優(yōu)化,因為一般n都是超大數(shù),而e則比較小,所以d也會很大,這里就需要大量的循環(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;}}

因為 (d * e) % m = 1也就是

d * e = k * m + 1

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

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

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

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

Ci = Mie mod n

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

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

Mi = Cid mod n

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

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

以加密為例

Ci = Mie mod n

因為需要考慮大數(shù)的問題,所以模的冪運算不能直接運算,比如如果我先直接計算Mie,由于Mi有可能是很大的數(shù),這樣它的e次冪就會是一個超級數(shù)字,計算機無法計算和存儲

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

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

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

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

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

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

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

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

因為a%n取模一定比a小,所以a%n*a就要比a2小很多,類推

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

得出

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

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

代碼:

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)然,上面僅僅是簡單例子,因為如果冪數(shù)較大比如d就會是一個超大數(shù),這樣循環(huán)次數(shù)就會很多,計算時間很長。

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

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

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

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

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

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

se % n = ((se - 1 % n) * e) % 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、利用遞歸二分。因為開方所以每個節(jié)點的兩個子節(jié)點都相等,所以計算其中一個就可以,這樣我們只需計算二叉樹的一條路徑就可以了,整體復(fù)雜度只有O(log2n)。比如2n只需要計算n + x次(最多壞情況每次都是奇數(shù)則是2n),比2n次計算節(jié)省大量的時間,而且數(shù)據(jù)越大節(jié)省時間越多。

2、位運算。在判斷奇偶數(shù)時,沒有使用除法,因為除法運算復(fù)雜度很大,耗時比其他運算長很多。這里使用位運算,只需判斷最低位是否為0即可,而除2運算則可以用右移一位代替。因為計算機中位運算最快,所以這樣會節(jié)省大量的時間。

正確性驗證

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

首先加密

k = se % n

然后對k解密

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

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

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

通過之前的計算可知 (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ù)費馬小定理,如果a和b互質(zhì),則

ab-1 = 1 mod b

所以考慮兩種情況:

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

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

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

sp-1 = 1 mod p

sp-1 % p = 1

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

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

因為sp-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)

因為pq = n所以最終

r = s % n

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

所以 r = s 驗證了RSA的正確性。

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

總結(jié)

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

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