網上有不少RSA講解,可是看了我這篇,你必定能徹底弄明白RSA
RSA是一種非對稱加密算法,要加密一段數據,首先咱們要拿到公鑰和私鑰。git
首選取兩個互質數 p q
那麼p * q 獲得 N
這時我要計算出φ(N)
φ函數φ(N)是小於或等於N的正整數中與N互質的數的數目。github
根據歐拉公式,我知道算法
φ(N) = (p-1)*(q-1)
固然前提p q都是質數安全
如今咱們舉例子
首先我選擇兩個互質數 p=11 q=13
因此N = pq = 1113 = 143
根據公式獲得φ(N) = 120
這時候咱們隨機選擇一個整數e,條件是1< e < φ(n),且e與φ(n) 互質。
如今咱們選擇e =7
接着咱們計算e對φ(n)的模逆元函數
根據歐拉定理)獲得的公式加密
e*d ≡ 1 (mod φ(n))
這個公式簡單的說就是 e*d除以φ(N)獲得的餘數爲1code
這個公式能夠轉換成ip
e*d - 1 = kφ(n)
因此,已知 e = 7 φ(n) = 120get
7d + 120*k = 1
展轉相除法計算d博客
120 = 7 * 17 + 1 17 = 17 * 1 1 = 120 * 1 + 7 * (-17) 1 = 120 * 1 + 7 *(-17) 最終得出,d = -17 k = 1
雖然咱們獲得了 d=-17但 在rsa中 d必須是一個正整數,在工程中,RSA的pq會無窮大過公鑰質數e ,因此根本不會出現這種情況。可是若是出現負數,咱們會將它翻轉
if(d<0) d=d+φ(n)
因此獲得 e對φ(n)的模逆元 爲 120 + (-17)也就是103
RSA中 公鑰就是 N,e 而 私鑰就是N,d
咱們上面的例子 公鑰 (143,7) 私鑰(143, 103)
加密
m^e ≡ c (mod n)
要加密的m = 13
13^7 = 117 (mod 143)
解密
c^d ≡ m (mod n)
要解密的是c = 117
117^103 = 13 (mod 143)
上面能夠用快速冪取餘來計算出餘數
#include <stdio.h> long PowerMod (int a, int b, int c) { int ans = 1; a = a % c; while(b>0) { if(b % 2 == 1) ans = (ans * a) % c; b = b/2; // b>>=1; a = (a * a) % c; } return ans; }
rsa 爲何安全。
(1)ed≡1 (mod φ(n))。只有知道e和φ(n),才能算出d。 (2)φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。 (3)n=pq。只有將n因數分解,才能算出p和q。
這段轉自阮一峯大大的博客
道理很簡單,只要能將N進行因式分解,那麼RSA的就再也不安全。
因此然你可因式分解143 = 13* 11
可是你不可能分解
18728736598172301274983275897298461982739812703985619727398173 * 13824985149871927398172398479818203801740957019283098109283757
最後附上一個擴展歐幾里得算法,也就是擴展展轉相除法的c實現
int gcdEx(int a, int b, int *x, int *y) { if(b==0) { *x = 1,*y = 0; return a; } else { int r = gcdEx(b, a%b, x, y); /* r = GCD(a, b) = GCD(b, a%b) */ int t = *x; *x = *y; *y = t - a/b * *y; return r; } }
固然,最後仍是再換個其餘的數來計算一遍擴展展轉相除法
53 102 互質
102 = 53 *1 +49 53 = 49 *1 + 4 49 = 12 * 4 + 1 //餘數放到前面 49 = 102*1 + 53*(-1) 4 = 53*1 +49 *(-1) 1 = 49 * 1 + 4 *(-12) //放回去 1 = 49 * 1 + 4 *(-12) 1 = 49 * 1 + [53*1 +49 *(-1)] *(-12) 1 = 49*(13)+53*(-12) 1 = [102*1 + 53*(-1)]*13 + 53*(-12) 1 = 102 * 13 + 53* (-25)
最後在 用
102 + (-25) 得出 53 對102 的逆元 爲77
其餘文章