RSA算法
RSA算法可以說是使用最爲廣泛的非對稱加密算法。在1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的,並取三人名字的首字母命名。其中的數學原理大致如下:
加密過程
RSA加密過程簡單描述如下:
- 選兩個大質數 ,計算;
- 選一個大於1的整數,滿足和 互質,要小於後者;
- 數據加密後爲,那麼加密後的數據 ;
這裏就作爲公鑰。其中是的歐拉函數。
解密過程
- 找到一個數字,滿足 ;
- 數據解密還原爲 ,那麼 ;
這裏就作爲私鑰。其中是對的模反元素。
舉例
- 取,那麼;
- 取, 與互質,公鑰;
- 取, 滿足,私鑰;
- 加密數字,那麼;
- 解密數據, 那麼;
使用python內置的pow函數, pow(x,y[,z])
就是x的y次方對z取模。
>>> x = 20
>>> y = pow(x, 3, 187) # 公鑰(187, 3), 加密x
>>> y
146
>>> pow(y, 107, 187) # 私鑰(187, 107), 解密y
20
應用場景
通過前面RSA的數學過程可以看出,公鑰私鑰在加解密上是對稱的,即公鑰加密私鑰解密,私鑰加密公鑰也可以解密。那麼結合公鑰私鑰的公開與保密特點,可以看出有如下經典實用場景:
- 數據加密:公鑰廣而告之,公鑰所有者都可加密數據,只有私鑰所有者可以解密數據;
- 數字簽名:私鑰私密擁有,只有私鑰所有者可以製作數字簽名,任何有公鑰的人可驗證簽名;
這裏再詳細說一下數字簽名。數字簽名通常還需要結合摘要算法。完整的數據報文通過摘要算法hash出一個固定長度的字符串,比如Git使用的SHA1算法,文件MD5算法等。然後對摘要內容使用私鑰加密生成數字簽名。對方驗證數字簽名的時候,也是先用同樣的摘要算法算出摘要,然後使用公鑰解密簽名還原摘要,對比兩者是否相同。
理論證明
RSA算法用到的數論知識有:歐拉定理、費馬小定理、擴展歐幾里得算法(生成一組公私鑰)。理解這些數論原理的證明是有一定難度,但是通過這些數論原理來理解RSA的如何加密解密就相對簡單了,致敬那些偉大的數學家。
在知乎上如何用通俗易懂的話來解釋非對稱加密,有個回答很形象:
讓對方任意想一個3位數,並把這個數和91相乘,然後告訴我積的最後三位數,我就可以猜出對方想的是什麼數字啦!
比如對方想的是123,那麼對方就計算出123 * 91等於11193,並把結果的末三位193告訴我。看起來,這麼做似乎損失了不少信息,讓我沒法反推出原來的數。不過,我仍然有辦法:只需要把對方告訴我的結果再乘以11,乘積的末三位就是對方剛開始想的數了。可以驗證一下,193 * 11 = 2123,末三位正是對方所想的祕密數字!
其實道理很簡單,91乘以11等於1001,而任何一個三位數乘以1001後,末三位顯然都不變(例如123乘以1001就等於123123)。