深入理解RSA演算法
本文結構:
- 一些基本的數學知識
- RSA的具體過程
- 為什麼RSA的私鑰解密一定能得到明文
- RSA演算法可靠嗎
- RSA演算法的一些其他特徵
假設alice想要通過rsa演算法在公網上,將訊息加密傳遞給bob,他們應該怎麼做呢?
分為以下幾個步驟:
1.bob生成一堆共私鑰,將公鑰在網上公開,私鑰自己儲存
2.alice通過bob的公鑰加密明文訊息m,得到密文c,並將密文c傳遞給bob
3.bob用自己的私鑰解密密文c,得到明文m
一些基本的數學知識
- 質數(素數)p :只有1和他本身能被自己整除。
-
互質
:如果兩個正整數,除了1以外,沒有其他公因子,我們就稱這兩個數是ofollow,noindex">互質關係
比如,15和32沒有公因子,所以它們是互質關係。這說明,不是質數也可以構成互質關係。 - 尤拉函式φ(n) :小於n的正整數中,與n互質的整數的個數。例如φ(8)=4(因為小於8的正整數中只有1,3,5,7與8互質)
- 若n為質數,則φ(n)=n-1
- n如果可以分為兩個質數(p,q)的乘積,則φ(n)=φ(p*q)=φ(p)φ(q)=(p-1)(q-1)
- 尤拉定理 :如果兩個正整數a和n互質,則:
a^φ(n)≡1 mod n。
特別的,當n為質數時: a^(n-1)≡1 mod n
- 模反元素 : 如果兩個正整數a和n互質,那麼一定可以找到整數b,滿足:
a×b≡1 mod n
(ab-1 被n整除,或者說ab被n除的餘數是1)
這時,b就叫做a的"模反元素" 。
RSA的具體過程:
祕鑰的產生
- bob選擇兩個保密的大質數p和q(這裡假設是p=61,q=53)
-
計算n=p×q=61×53=3233,φ(n)=φ(p*q)=φ(p)φ(q)=(p-1)(q-1)=60×52=3120
這裡n的長度就是祕鑰的長度 。3233寫成二進位制是110010100001,一共有12位,所以這個金鑰就是12位。 -
選一個整數e,滿足1< e < φ(n),且e與φ(n) 互質。
bob就在1到3120之間,隨機選擇了17。(實際應用中,常常選擇65537。) - 求解e關於φ(n)的模反元素d(由於e與φ(n)互質,所以d一定存在)
ed ≡ 1 (mod φ(n)) 等價於 ed - 1 = kφ(n),這裡就是17d-1 =3120k
很容易求得(d,k)=(2753,-15),即 d=2753。
-
n和e封裝成公鑰,n和d封裝成私鑰
這個例子中 n=3233,e=17,d=2753,所以公鑰就是 (3233,17),私鑰就是(3233, 2753)。
加密
假設alice要向bob傳送明文資訊m,則用bob的公鑰 (n,e) 對m進行加密。
並且加密時必須將明文進行位元串分組,保證每個分組對應的十進位制數小於n,即保證m<n。
c ≡ m^e (mod n)
這裡m假設是65,那麼可以算出下面的等式:65^17 ≡ 2790 (mod 3233)
於是,c等於2790,alice就把2790發給了bob。
解密
bob拿到2790以後,就用自己的私鑰(n=3233, d=2753) 進行解密。
m ≡ c^d (mod n)
現在,c等於2790,私鑰是(3233, 2753),那麼,bob算出
2790^2753 ≡ 65 (mod 3233)
因此,bob知道了alice加密前的原文就是65。
為什麼RSA的私鑰解密一定能得到明文
對於密文的解密運算為:
m ≡ c^d (mod n)
現在來證明上面的公式恆成立。將c ≡ m^e (mod n) 代入右邊,可得
右邊=c^d (mod n)=(m^e )^d(mod n) = m^(ed)(mod n)
又由於ed ≡ 1 (mod φ(n)) 可知必有ed=kφ(n)+1 ,故有
右邊=m^(ed)(mod n) = m^(kφ(n)+1)(mod n)
下面分兩種情況證明m^(kφ(n)+1)(mod n) = m :
1)明文m與n互質。那麼由尤拉定理知
m^φ(n) ≡ 1 mod n
於是 m^( kφ(n) ) ≡ 1 mod n
於是 m^( kφ(n) + 1 ) ≡ m mod n = m
2)明文m與n不互質:
m與n不互質,說明m與n有公因子。
又因為n=pq,且p和q都為質數,所以n的因子只有p,q,那麼m與n的公因子只能是p或者q。所以m為p或q的倍數 。
假設m=tp,(t為一正整數),且t與q互質 (若t與q不互質,假設t=kq,則m=tp=kpq=kn,違反了m<n)
因為m=tp與q互質,由尤拉定理知
m^φ(q)≡ 1 mod q
兩邊同時取kφ(p)次方,得
[m^φ(q) ]^(kφ(p)) ≡ 1 mod q
==>m^[kφ(q)φ(p)] ≡ 1 mod q
==>m^(kφ(n)) ≡ 1 mod q
==>m^(kφ(n)) = 1 + rq (r為一正整數)
==>m^(kφ(n)+1) = tp(1 + rq) = tp + tprq = m + trn(兩邊同時乘上m=tp)
==>m^(kφ(n)+1) ≡ m mod n
m ≡ c^d (mod n) 得證。
RSA演算法可靠嗎
回顧上面的金鑰生成步驟,一共出現六個數字:
p(保密) q(保密) n(公開) φ(n)(保密) e(公開) d(保密)
公鑰用到了兩個(n和e),私鑰用到了兩個(n和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就可以算出,也就意味著私鑰被破解
但是大整數的因數分解是非常困難的,n越大,演算法約安全,目前推薦用的rsa祕鑰長度為2018及上。
"對極大整數做因數分解的難度決定了RSA演算法的可靠性。換言之,對一極大整數做因數分解愈困難,RSA演算法愈可靠。
RSA演算法的一些其他特徵
同祕鑰RSA有乘法同態。
簡單來說:
假設:明文m=m1 * m2 , 且c1位m1對應的密文,c2位m2對應密文。
則:m對應的密文m=c1 * c2
原理:
若: A * B = C mod n
則 :A^d ∗ Bd=C d mod n
同價加密的一些相關知識:https://yeasy.gitbooks.io/blockchain_guide/content/crypto/homoencryption.html