RSA加密算法詳解(二)

研究RSA

不知爲什麼,這幾天忽然有些心煩。望蒼茫大地,憑添幾分憂傷,多是下雨的緣故。本篇主要想詳細介紹RSA加密算法的原理,常常聽別人說,這裏是本身想搞清楚,弄明白。首先介紹了基本的數學原理,而後給出一個具體的計算例子和相關的理論充分性證實。

皓眸大前端開發學習皓眸大前端開發學習


轉載請註明出處:http://www.haomou.net/2014/08/27/2014_rsa/
前端

RSA由來

1976年之前,全部的加密方法都是同一種模式:
  (1)甲方選擇某一種加密規則,對信息進行加密;
  (2)乙方使用同一種規則,對信息進行解密。
因爲加密和解密使用一樣規則(簡稱」密鑰」),這被稱爲」對稱加密算法」(Symmetric-key algorithm)。這種加密模式有一個最大弱點:甲方必須把加密規則告訴乙方,不然沒法解密。保存和傳遞密鑰,就成了最頭疼的問題。
皓眸大前端開發學習皓眸大前端開發學習
1976年,兩位美國計算機學家Whitfield Diffie 和 Martin、Hellman,提出了一種嶄新構思,能夠在不直接傳遞密鑰的狀況下,完成解密。這被稱爲」Diffie-Hellman密鑰交換算法」。這個算法啓發了其餘科學家。人們認識到,加密和解密可使用不一樣的規則,只要這兩種規則之間存在某種對應關係便可,這樣就避免了直接傳遞密鑰。這種新的加密模式被稱爲」非對稱加密算法」。
  (1)乙方生成兩把密鑰(公鑰和私鑰)。公鑰是公開的,任何人均可以得到,私鑰則是保密的。
  (2)甲方獲取乙方的公鑰,而後用它對信息加密。
  (3)乙方獲得加密後的信息,用私鑰解密。
若是公鑰加密的信息只有私鑰解得開,那麼只要私鑰不泄漏,通訊就是安全的。
皓眸大前端開發學習皓眸大前端開發學習
1977年,三位數學家Rivest、Shamir 和 Adleman 設計了一種算法,能夠實現非對稱加密。這種算法用他們三我的的名字命名,叫作RSA算法。從那時直到如今,RSA算法一直是最廣爲使用的」非對稱加密算法」。絕不誇張地說,只要有計算機網絡的地方,就有RSA算法。
這種算法很是可靠,密鑰越長,它就越難破解。根據已經披露的文獻,目前被破解的最長RSA密鑰是768個二進制位。也就是說,長度超過768位的密鑰,還沒法破解(至少沒人公開宣佈)。所以能夠認爲,1024位的RSA密鑰基本安全,2048位的密鑰極其安全。
下面,我就進入正題,解釋RSA算法的原理。文章共分紅兩部分,今天是第一部分,介紹要用到的四個數學概念。你能夠看到,RSA算法並不難,只須要一點數論知識就能夠理解。
算法

理論基礎

這裏介紹一點理論基礎,都是比較簡單的,小學的數學知識。看我細細道來~安全

####什麼是「素數」?
素數是這樣的整數,它除了能表示爲它本身和1的乘積之外,不能表示爲任何其它兩個整數的乘積。例如,15=3*5,因此15不是素數;又如,12=6*2=4*3,因此12也不是素數。另外一方面,13除了等於13*1之外,不能表示爲其它任何兩個整數的乘積,因此13是一個素數。素數也稱爲「質數」。網絡

####什麼是「互質數」(或「互素數」)?
小學數學教材對互質數是這樣定義的:「公約數只有1的兩個數,叫作互質數。」這裏所說的「兩個數」是指天然數。
  判別方法主要有如下幾種(不限於此):
(1)兩個質數必定是互質數。例如,2與七、13與19。
(2)一個質數若是不能整除另外一個合數,這兩個數爲互質數。例如,3與十、5與 26。
(3)1不是質數也不是合數,它和任何一個天然數在一塊兒都是互質數。如1和9908。
(4)相鄰的兩個天然數是互質數。如 15與 16。
(5)相鄰的兩個奇數是互質數。如 49與 51。
(6)大數是質數的兩個數是互質數。如97與88。
(7)小數是質數,大數不是小數的倍數的兩個數是互質數。如 7和 16。
(8)兩個數都是合數(二數差又較大),小數全部的質因數,都不是大數的約數,這兩個數是互質數。如357與715,357=3×7×17,而三、7和17都不是715的約數,這兩個數爲互質數。等等。函數

####什麼是模指數運算?
指數運算誰都懂,沒必要說了,先說說模運算。模運算是整數運算,有一個整數m,以n爲模作模運算,即m mod n。怎樣作呢?讓m去被n整除,只取所得的餘數做爲結果,就叫作模運算。例如,10 mod 3=1;26 mod 6=2;28 mod 2 =0等等。
  模指數運算就是先作指數運算,取其結果再作模運算。如2^3 mod 5 = 3工具

什麼是同餘式

表示同餘關係的數學表達式,與等式類似。將等式中的等號「=」換成同餘符號「≡」,必要時在式尾綴以(mod m) 註明模m(即除數),就是同餘式。含有未知數的同餘式叫作同餘方程,一般要求整數解。
若是兩個正整數 a和 b之差能被 n整除,那麼咱們就說 a和 b對模n同餘,記做:
a ≡b (mod n)性能

####什麼是費馬定理
若p是素數,a與p互素,則
a^(p-1)≡1 (mod p)學習

什麼是歐拉定理

歐拉函數φ(n)表示不大於n且與n互素的正整數的個數。
當n是素數,φ(n)=n-1。n=pq,p,q均爲素數時,則φ(n)= φ(p)φ(q)=(p-1)(q-1)。
對於互素的a和n,有a^φ(n)≡1(mod n)編碼

什麼是模反元素?

若是兩個正整數a和n互質,那麼必定能夠找到整數b,使得ab-1被n整除或者說ab被n除的餘數是1。這時,b就叫作a的」模反元素」。
好比,3和11互質,那麼3的模反元素就是4,由於 (3 × 4)-1 能夠被11整除。顯然,模反元素不止一個, 4加減11的整數倍都是3的模反元素 {…,-18,-7,4,15,26,…},即若是b是a的模反元素,則 b+kn 都是a的模反元素。歐拉定理能夠用來證實模反元素必然存在。加密

密鑰生成步驟

這裏經過實例來講明。假設愛麗絲要與鮑勃進行加密通訊,她該怎麼生成公鑰和私鑰呢?
皓眸大前端開發學習皓眸大前端開發學習
第一步,隨機選擇兩個不相等的質數p和q。
愛麗絲選擇了61和53。(實際應用中,這兩個質數越大,就越難破解。)
第二步,計算p和q的乘積n。
愛麗絲就把61和53相乘。
  n = 61×53 = 3233
n的長度就是密鑰長度。3233寫成二進制是110010100001,一共有12位,因此這個密鑰就是12位。實際應用中,RSA密鑰通常是1024位,重要場合則爲2048位。
第三步,計算n的歐拉函數φ(n)。
根據公式:
  φ(n) = (p-1)(q-1)
愛麗絲算出φ(3233)等於60×52,即3120。
第四步,隨機選擇一個整數e,條件是1< e < φ(n),且e與φ(n) 互質。
愛麗絲就在1到3120之間,隨機選擇了17。(實際應用中,經常選擇65537。)
第五步,計算e對於φ(n)的模反元素d。
所謂」模反元素」就是指有一個整數d,可使得ed被φ(n)除的餘數爲1。
  ed ≡ 1 (mod φ(n))
這個式子等價於
  ed - 1 = kφ(n)
因而,找到模反元素d,實質上就是對下面這個二元一次方程求解。
  ex + φ(n)y = 1
已知 e=17, φ(n)=3120,
  17x + 3120y = 1
這個方程能夠用」擴展歐幾里得算法」求解,此處省略具體過程。總之,愛麗絲算出一組整數解爲 (x,y)=(2753,-15),即 d=2753。
至此全部計算完成。
第六步,將n和e封裝成公鑰,n和d封裝成私鑰。
在愛麗絲的例子中,n=3233,e=17,d=2753,因此公鑰就是 (3233,17),私鑰就是(3233, 2753)。
實際應用中,公鑰和私鑰的數據都採用ASN.1格式表達。以下:
皓眸大前端開發學習皓眸大前端開發學習
好比上面顯示的這個公鑰,那麼怎麼看出加密指數和模數呢?

下面是我隨便從IE裏導出的一個證書的公鑰

1
30 81 89 02 81 81 00 ee fa 1f c9 b0 43 df 7e 75 81 4e 31 71 91 0b fc 15 9d d9 4a 8a 51 f5 09 18 c6 7c c5 f1 27 c4 01 62 fc bf fc 84 29 a6 2f e6 1e 02 06 0b 96 89 d3 42 b1 73 9f 02 ae 75 62 09 3f 83 80 34 46 60 39 0a e3 21 4e e7 04 42 d5 7e 5e 98 45 27 5d 04 b9 27 32 c0 65 a4 94 85 13 25 db 16 f2 fb 51 c7 ff 28 62 d1 83 31 4f a9 a4 f4 c5 4f 9d 00 2e 14 3f 95 16 9c 4e 25 07 1b d5 7d 38 71 d8 40 f8 aa 71 02 03 01 00 01

 

在PKCS#1中的RSA的公鑰的標準格式爲

1
2
3
4
5
6
7
PKCS#1 :
An RSA public key should be represented with the ASN.1 type RSAPublickey:

RSAPublickey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}

 

而後按照ASN的標準編碼,因此說:

1
2
3
4
5
6
30 81 89 02 81 81 00 ee fa 1f c9 b0 43 df 7e 75 81 4e 31 71 91 0b fc 15 
9d d9 4a 8a 51 f5 09 18 c6 7c c5 f1 27 c4 01 62 fc bf fc 84 29 a6 2f e6 1e
02 06 0b 96 89 d3 42 b1 73 9f 02 ae 75 62 09 3f 83 80 34 46 60 39 0a e3
21 4e e7 04 42 d5 7e 5e 98 45 27 5d 04 b9 27 32 c0 65 a4 94 85 13 25 db
16 f2 fb 51 c7 ff 28 62 d1 83 31 4f a9 a4 f4 c5 4f 9d 00 2e 14 3f 95 16 9c 4e
25 07 1b d5 7d 38 71 d8 40 f8 aa 71 02 03 01 00 01

 

0x30 0x81 0x89 是一個標識頭,整個編碼應該是:

1
2
3
4
5
6
02 81 81 00 ee fa 1f c9 b0 43 df 7e 75 81 4e 31 71 91 0b fc 15 9d d9 4a 
8a 51 f5 09 18 c6 7c c5 f1 27 c4 01 62 fc bf fc 84 29 a6 2f e6 1e 02 06 0b
96 89 d3 42 b1 73 9f 02 ae 75 62 09 3f 83 80 34 46 60 39 0a e3 21 4e e7
04 42 d5 7e 5e 98 45 27 5d 04 b9 27 32 c0 65 a4 94 85 13 25 db 16 f2 fb
51 c7 ff 28 62 d1 83 31 4f a9 a4 f4 c5 4f 9d 00 2e 14 3f 95 16 9c 4e 25 07
1b d5 7d 38 71 d8 40 f8 aa 71 02 03 01 00 01

 

1
2
3
4
5
6
02 81 81 00 ee fa 1f c9 b0 43 df 7e 75 81 4e 31 71 91 0b fc 15 9d d9 4a 
8a 51 f5 09 18 c6 7c c5 f1 27 c4 01 62 fc bf fc 84 29 a6 2f e6 1e 02 06 0b
96 89 d3 42 b1 73 9f 02 ae 75 62 09 3f 83 80 34 46 60 39 0a e3 21 4e e7
04 42 d5 7e 5e 98 45 27 5d 04 b9 27 32 c0 65 a4 94 85 13 25 db 16 f2 fb
51 c7 ff 28 62 d1 83 31 4f a9 a4 f4 c5 4f 9d 00 2e 14 3f 95 16 9c 4e 25 07
1b d5 7d 38 71 d8 40 f8 aa 71

 

是n的編碼。

0x02 0x03 0x01 0x00 0x01是e的編碼,不過你仍是看不出來這什麼整數,
舉個例子
對於上面的0x02,0x03,0x01,0x00,0x01 其中0x02,0x03是e的編碼的標識頭
e的表示是0x01,0x00,0x01,因此e就是0x01256^2+0x00256^1+1=65537

同理n就是

1
2
3
4
5
6
81 00 ee fa 1f c9 b0 43 df 7e 75 81 4e 31 71 91 0b fc 15 9d d9 4a 8a 51 f5 
09 18 c6 7c c5 f1 27 c4 01 62 fc bf fc 84 29 a6 2f e6 1e 02 06 0b 96 89 d3
42 b1 73 9f 02 ae 75 62 09 3f 83 80 34 46 60 39 0a e3 21 4e e7 04 42 d5
7e 5e 98 45 27 5d 04 b9 27 32 c0 65 a4 94 85 13 25 db 16 f2 fb 51 c7 ff 28
62 d1 83 31 4f a9 a4 f4 c5 4f 9d 00 2e 14 3f 95 16 9c 4e 25 07 1b d5 7d 38
71 d8 40 f8 aa 71 02 03 01 00 01

 

注意,這個是一個整數的編碼,也要像e,那樣解碼。

RSA算法的可靠性

回顧上面的密鑰生成步驟,一共出現六個數字:

1
2
3
4
5
6
  p
  q
  n
  φ(n)
  e
  d

 

這六個數字之中,公鑰用到了兩個(n和e),其他四個數字都是不公開的。其中最關鍵的是d,由於n和d組成了私鑰,一旦d泄漏,就等於私鑰泄漏。
那麼,有無可能在已知n和e的狀況下,推導出d?
  (1)ed≡1 (mod φ(n))。只有知道e和φ(n),才能算出d。
  (2)φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。
  (3)n=pq。只有將n因數分解,才能算出p和q。
結論:若是n能夠被因數分解,d就能夠算出,也就意味着私鑰被破解。
但是,大整數的因數分解,是一件很是困難的事情。目前,除了暴力破解,尚未發現別的有效方法。維基百科這樣寫道:
  「對極大整數作因數分解的難度決定了RSA算法的可靠性。換言之,對一極大整數作因數分解愈困難,RSA算法愈可靠。
  假若有人找到一種快速因數分解的算法,那麼RSA的可靠性就會極度降低。但找到這樣的算法的可能性是很是小的。今天只有短的RSA密鑰纔可能被暴力破解。到2008年爲止,世界上尚未任何可靠的攻擊RSA算法的方式。
  只要密鑰長度足夠長,用RSA加密的信息其實是不能被解破的。」
舉例來講,你能夠對3233進行因數分解(61×53),可是你無法對下面這個整數進行因數分解。

1
2
3
4
5
6
7
8
9
  12301866845301177551304949
  58384962720772853569595334
  79219732245215172640050726
  36575187452021997864693899
  56474942774063845925192557
  32630345373154826850791702
  61221429134616704292143116
  02221240479274737794080665
  351419597459856902143413

 

它等於這樣兩個質數的乘積:

1
2
3
4
5
6
7
8
9
10
11
  33478071698956898786044169
  84821269081770479498371376
  85689124313889828837938780
  02287614711652531743087737
  814467999489
    ×
  36746043666799590428244633
  79962795263227915816434308
  76426760322838157396665112
  79233373417143396810270092
  798736308917

 

事實上,這大概是人類已經分解的最大整數(232個十進制位,768個二進制位)。比它更大的因數分解,尚未被報道過,所以目前被破解的最長RSA密鑰就是768位。

加密和解密

有了公鑰和密鑰,就能進行加密和解密了。
(1)加密要用公鑰 (n,e)
假設鮑勃要向愛麗絲髮送加密信息m,他就要用愛麗絲的公鑰 (n,e) 對m進行加密。這裏須要注意,m必須是整數(字符串能夠取ascii值或unicode值),且m必須小於n。
所謂」加密」,就是算出下式的c:

1
  me ≡ c (mod n)

c = m^e%n

 

愛麗絲的公鑰是 (3233, 17),鮑勃的m假設是65,那麼能夠算出下面的等式:

1
  6517 ≡ 2790 (mod 3233)

 

因而,c等於2790,鮑勃就把2790發給了愛麗絲。
(2)解密要用私鑰(n,d)
愛麗絲拿到鮑勃發來的2790之後,就用本身的私鑰(3233, 2753) 進行解密。能夠證實,下面的等式必定成立:

1
  cd ≡ m (mod n)

m=c^d%n 

 

也就是說,c的d次方除以n的餘數爲m。如今,c等於2790,私鑰是(3233, 2753),那麼,愛麗絲算出

1
  27902753 ≡ 65 (mod 3233)

 

所以,愛麗絲知道了鮑勃加密前的原文就是65。
至此,」加密–解密」的整個過程所有完成。
咱們能夠看到,若是不知道d,就沒有辦法從c求出m。而前面已經說過,要知道d就必須分解n,這是極難作到的,因此RSA算法保證了通訊安全。
你可能會問,公鑰(n,e) 只能加密小於n的整數m,那麼若是要加密大於n的整數,該怎麼辦?有兩種解決方法:一種是把長信息分割成若干段短消息,每段分別加密;另外一種是先選擇一種」對稱性加密算法」(好比DES),用這種算法的密鑰加密信息,再用RSA公鑰加密DES密鑰。

私鑰解密的證實

最後,咱們來證實,爲何用私鑰解密,必定能夠正確地獲得m。也就是證實下面這個式子:

1
c^d ≡ m (mod n)

 

由於,根據加密規則

1
m^e ≡ c (mod n)

 

因而,c能夠寫成下面的形式:

1
c = m^e - kn

 

將c代入要咱們要證實的那個解密規則:

1
(m^e - kn)^d ≡ m (mod n)

 

它等同於求證

1
m^ed ≡ m (mod n)

 

因爲

1
ed ≡ 1 (mod φ(n))

 

因此

1
ed = hφ(n)+1

 

將ed代入:

1
m^(hφ(n)+1) ≡ m (mod n)

 

接下來,分紅兩種狀況證實上面這個式子。
(1)m與n互質。
根據歐拉定理,此時

1
  m^φ(n) ≡ 1 (mod n)

 

獲得

1
  (m^φ(n))^h × m ≡ m (mod n)

 

原式獲得證實。
(2)m與n不是互質關係。
此時,因爲n等於質數p和q的乘積,因此m必然等於kp或kq。
以 m = kp爲例,考慮到這時k與q必然互質,則根據歐拉定理,下面的式子成立:

1
  (kp)^q-1 ≡ 1 (mod q)

 

進一步獲得

1
  [(kp)^q-1]^h(p-1) × kp ≡ kp (mod q)

 

1
  (kp)^ed ≡ kp (mod q)

 

將它改寫成下面的等式

1
  (kp)^ed = tq + kp

 

這時t必然能被p整除,即 t=t’p

1
  (kp)^ed = t'pq + kp

 

由於 m=kp,n=pq,因此

1
  m^ed ≡ m (mod n)

 

原式獲得證實。

RSA缺陷

當p和q是一個大素數的時候,從它們的積pq去分解因子p和q,這是一個公認的數學難題。好比當pq大到1024位時,迄今爲止尚未人可以利用任何計算工具去完成分解因子的任務。所以,RSA從提出到如今已近二十年,經歷了各類攻擊的考驗,逐漸爲人們接受,廣泛認爲是目前最優秀的公鑰方案之一。  然而,雖然RSA的安全性依賴於大數的因子分解,但並無從理論上證實破譯RSA的難度與大數分解難度等價。即RSA的重大缺陷是沒法從理論上把握它的保密性能如何。  此外,RSA的缺點還有:A)產生密鑰很麻煩,受到素數產生技術的限制,於是難以作到一次一密。B)分組長度太大,爲保證安全性,n 至少也要 600 bits 以上,使運算代價很高,尤爲是速度較慢,較對稱密碼算法慢幾個數量級;且隨着大數分解技術的發展,這個長度還在增長,不利於數據格式的標準化。所以,使用RSA只能加密少許數據,大量的數據加密還要靠對稱密碼算法。

相關文章
相關標籤/搜索