前言:在RSA誕生之前
RSA算法是最重要算法之一
它是計算機通信安全的基石,安全可靠
只要有計算機網絡的地方,就有RSA算法
在它誕生之前,即1976年以前,加解密信息使用同一種規則
- 甲方選擇某一種加密規則,對信息進行加密;
- 乙方使用同一種規則,對信息進行解密。
雖然理論上,只要加解密“規則”(即“密鑰”)足夠復雜,這種方式也可安全的傳遞信息
但這種方法最大的弱點就是,密鑰在傳遞的過程中易被泄露
這種加密和解密使用同樣規則的方法,被稱為“對稱加密算法”
RSA算法
倘若在加解密信息的過程中,能讓加密密鑰(公鑰)與解密密鑰(私鑰)不同,即
- 甲要傳密信給乙,乙先根據某種算法得出本次與甲通信的公鑰與私鑰;
- 乙將公鑰傳給甲(公鑰可以讓任何人知道,即使泄露也沒有任何關系);
- 甲使用乙傳給的公鑰加密要發送的信息原文m,發送給乙密文c;
- 乙使用自己的私鑰解密密文c,得到信息原文m .
就可以很好的克服對稱加密算法的弱點,這種新的加密模式被稱為“非對稱加密算法”
可以觀察到,從始至終,私鑰一直都在信息接收方乙處
只要乙自己不泄露出去,私鑰就沒有泄露的可能
1977年,三位數學家Rivest、Shamir和Adleman設計了一種算法,可以實現非對稱加密
這種算法用他們三個人的名字首字母命名,叫做RSA算法
RSA算法非常可靠,密鑰越長,它就越難破解
至於難以破解的原理(安全性),在本文介紹完該算法后會有簡要說明
下面,先介紹一些基本概念與數學定理
質數與互質數
這是小學數學的概念
- 一個大於1的自然數,除了1和它本身外,不能被其他自然數整除(除0以外)的數稱之為質數(素數);否則稱為合數。
例如,15=3×5,所以15不是素數
13除了等於13×1以外,不能表示為其它任何兩個整數的乘積,所以13是一個素數
1不是質數,也不是合數
- 公約數只有1的兩個數,叫做互質數。
判斷或選取互質數的方法/定理有很多,如下所示
- 任意兩個質數一定構成互質數(如3與11、53與61);
- 大數是質數的兩個數一定是互質數(如97與88);
- 一個質數如果不能整除另一個合數,這兩個數為互質數;
即一個數是質數,另一個數只要不是前者的倍數,兩者就構成互質關系(如3與10、5與26); - 1和任何一個自然數在一起都是互質數;
- 相鄰的兩個自然數是互質數(如15與16);
- 相鄰的兩個奇數是互質數(如49與51)。
在RSA算法中,我們通常使用以上第1條與第2條
即選取兩個本身都是質數的數作為互質數
而以上第2條定理對於計算歐拉函數值有着積極作用
模運算
模運算的定義如下
- 讓m去被n整除,只取所得的余數作為結果,就叫做模運算。
例如,10 mod 3 = 1 、26 mod 6 = 2 、28 mod 2 = 0
同余
“≡”是數論中表示同余的符號
同余的定義如下
- 給定一個正整數m,如果兩個整數a和b滿足a-b能被m整除,即(a-b)modm=0,
那么就稱整數a與b對模m同余,記作a≡b(modm),同時可成立amodm=b
再次提醒注意,同余與模運算是不同的
a≡b(modm)僅可推出b=amodm
歐拉函數
歐拉函數本身需要一系列復雜推導,本部分僅介紹對認識RSA算法有幫助的部分
- 任意給定正整數n,計算在小於等於n的正整數之中,有多少個與n構成互質關系?
計算這個值的方法就叫做歐拉函數,以φ(n)表示.
例如,在1到8之中,與8形成互質關系的是1、3、5、7,所以φ(n)=4
在RSA算法中,我們需要明白歐拉函數對以下定理成立
- 如果n可以分解成兩個互質的整數之積,即n=p×q,則有:φ(n)=φ(pq)=φ(p)φ(q);
- 根據“大數是質數的兩個數一定是互質數”可以知道:
一個數如果是質數,則小於它的所有正整數與它都是互質數;
所以如果一個數p是質數,則有:φ(p)=p-1
由上易得,若我們知道一個數n可以分解為兩個質數p和q的乘積,則有
φ(n)=(p-1)(q-1)
歐拉定理與模反元素
歐拉函數的用處,在於歐拉定理
“歐拉定理”指的是
- 如果兩個正整數a和n互質,則n的歐拉函數φ(n)可以讓下面的等式成立:
aφ(n)≡1(modn)
也就是說,a的φ(n)次方被n除的余數為1
模反元素的推導過程如下
- 根據歐拉定理,有:
aφ(n)=a×aφ(n)−1≡1(modn)
令b=aφ(n)-1,得:
ab≡1(modn)
b就是a的模反元素
意即,如果兩個正整數a和n互質,那么一定可以找到整數b
使得ab-1被n整除,或者說ab被n除的余數是1
真實的例子
根據以上介紹的定義和數學知識
先來看一個真實的例子加深印象
假設甲要發送一串秘密數字m=65給乙
乙發送了一個公鑰(n,e)=(3233,17)給甲
甲根據以下公式及公鑰對密文m加密成c
me≡c(modn)
代入得
c=memodn=6517mod3233=2790
甲將使用公鑰加密的密文c=2790發送給乙
乙收到c=2790的密文后,使用私鑰(n,d)=(3233,2753)根據以下公式進行解密
cd=m(modn)
代入得
m=cdmodn=27902753mod3233=65
乙使用與公鑰不同的私鑰成功計算出密文m,發現了嗎?
從始至終,用來解密的私鑰(n,d)=(3233,2753)一直都在乙處,從未泄露
乙給甲的僅僅是用來加密的公鑰(3233,17)
這個公鑰並不能用來解密,即使被他人截獲,也沒有任何泄密的風險
那么,乙是如何計算出給甲的公鑰(3233,17)和私鑰(3233,2753)的呢?
計算密鑰
根據以上“真實的例子”
看看乙是如何計算密鑰(公鑰和私鑰)的
- 隨機選擇兩個不相等的質數p和q(乙選擇了61和53)
- 計算p和q的乘積n=p×q=61×53=3233
- 根據本文“歐拉函數”介紹過的公式
φ(n)=(p-1)(q-1)
代入計算n的歐拉函數值
φ(3233)=(61-1)×(53-1)=60×52=3120 - 隨機選擇一個整數e,條件是1<e<φ(n),且e與φ(n)互質
乙就在1到3120之間,隨機選擇了17 - 因為e與φ(n)互質,根據求模反元素的公式計算e,對於e的模反元素d有:
ed≡1(modφ(n))
這個式子等價於
(ed-1)/φ(n)=k(k為任意正整數)
即
ed-kφ(n)=1,代入數據得:
17d-3120k=1
實質上就是對以上這個二元一次方程求解
得到一組解為:(d,k)=(2753,-15) - 將n和e封裝成公鑰,n和d封裝成私鑰
n=3233,e=17,d=2753
所以公鑰就是(3233,17),私鑰就是(3233,2753)
其中,n的長度就是密鑰長度,3233寫成二進制是110010100001
一共有12位,所以這個密鑰就是12位
實際應用中,RSA密鑰一般是1024位,重要場合則為2048位
密鑰組成與加解密公式
公鑰KU | n:質數p和質數q的乘積(p和q必須保密) e:與(p-1)×(q-1)互質 |
私鑰KR | n:同公鑰n d:e-1(mod(p-1)(q-1)) |
加密 | c=memodn |
解密 | m=cdmodn |
安全性
根據以上實例,也許會有疑問
公鑰中已包含n=3233,我將其因式分解回n=3233=61×53
再根據乙計算密鑰的流程,不就可以根據公鑰得出私鑰了
事實上,RSA的安全性就是源自你沒辦法輕易的對大整數“因式分解”
上面的例子,密鑰長度是12位
因為這只是個示例,所以密鑰長度實在是太短了
你可以將示例中的n作因式分解,但是你沒法對下面這個整數進行因數分解
12301866845301177551304949
58384962720772853569595334
79219732245215172640050726
36575187452021997864693899
56474942774063845925192557
32630345373154826850791702
61221429134616704292143116
02221240479274737794080665
351419597459856902143413
它等於這樣兩個質數的乘積:
84821269081770479498371376
85689124313889828837938780
02287614711652531743087737
814467999489
79962795263227915816434308
76426760322838157396665112
79233373417143396810270092
798736308917
事實上,這大概是人類已經分解的最大整數(232個十進制位,768個二進制位)
對極大整數做因數分解的難度決定了RSA算法的可靠性
實際應用中,RSA密鑰一般是1024位(安全),重要場合則為2048位(極其安全)
一點感想
明天早上考大學生涯最后一門課程《網絡安全》
其中重點中的重點便是RSA算法
課本講得很隨意,還是得參考一些資料
包括阮一峰先生的兩篇文章《RSA算法原理(一)》、《RSA算法原理(二)》
和一些其它資料,如《用實例給新手講解RSA加密算法》
讀懂並整理加入了一些自己的想法,完成本文並共享之
就當學生考試生涯結束前的一點紀念吧
若有紕誤或不足,歡迎您留言指正