RSA加密算法原理和java简单实现
生活随笔
收集整理的這篇文章主要介紹了
RSA加密算法原理和java简单实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數學
RSA加密算法中,用到素數、互質數、指數運算、模運算等幾個數學知識。
素數
素數又稱質數,指在一個大于1的自然數中,除了1和此整數自身外,不能被其他自然數整除的數。
互質數
百度百科:公因數只有1的兩個數,叫做互質數。維基百科:互質,又稱互素。若N個整數的最大公因子是1,則稱這N個整數互質。
常見的互質數判斷方法主要有以下幾種:
兩個不同的質數一定是互質數。例如,2與7、13與19。
一個質數,另一個不為它的倍數,這兩個數為互質數。例如,3與10、5與 26。
相鄰的兩個自然數是互質數。如 15與 16。
相鄰的兩個奇數是互質數。如 49與 51。
較大數是質數的兩個數是互質數。如97與88。
小數是質數,大數不是小數的倍數的兩個數是互質數。例如 7和 16。
2和任何奇數是互質數。例如2和87。
1不是質數也不是合數,它和任何一個自然數在一起都是互質數。如1和9908。
輾轉相除法。
指數運算
指數運算又稱乘方計算,計算結果稱為冪。nm指將n自乘m次。把nm看作乘方的結果,叫做”n的m次冪”或”n的m次方”。其中,n稱為“底數”,m稱為“指數”。
模運算
模運算即求余運算?!澳!笔恰癕od”的音譯。和模運算緊密相關的一個概念是“同余”。數學上,當兩個整數除以同一個正整數,若得相同余數,則二整數同余。
兩個整數a,b,若它們除以正整數m所得的余數相等,則稱a,b對于模m同余,記作: a ≡ b (mod m);讀作:a同余于b模m,或者,a與b關于模m同余。例如:26 ≡ 14 (mod 12)。
RSA加密算法
公鑰與密鑰的產生
假設Alice想要通過一個不可靠的媒體接收Bob的一條私人訊息。她可以用以下的方式來產生一個公鑰和一個私鑰:
隨意選擇兩個大的質數p和q,p不等于q,計算N=pq。
根據歐拉函數,求得r = (p-1)(q-1)
選擇一個小于 r 的整數 e,求得 e 關于模 r 的模反元素,命名為d。(模反元素存在,當且僅當e與r互質)
將 p 和 q 的記錄銷毀。
(N,e)是公鑰,(N,d)是私鑰。Alice將她的公鑰(N,e)傳給Bob,而將她的私鑰(N,d)藏起來。
加密消息
假設Bob想給Alice送一個消息m,他知道Alice產生的N和e。他使用起先與Alice約好的格式將m轉換為一個小于N的整數n,比如他可以將每一個字轉換為這個字的Unicode碼,然后將這些數字連在一起組成一個數字。假如他的信息非常長的話,他可以將這個信息分為幾段,然后將每一段轉換為n。用下面這個公式他可以將n加密為c:
ne ≡ c (mod N)
計算c并不復雜。Bob算出c后就可以將它傳遞給Alice。
解密消息
Alice得到Bob的消息c后就可以利用她的密鑰d來解碼。她可以用以下這個公式來將c轉換為n:
cd ≡ n (mod N)
得到n后,她可以將原來的信息m重新復原。
解碼的原理是:
cd ≡ n e·d(mod N)
以及ed ≡ 1 (mod p-1)和ed ≡ 1 (mod q-1)。由費馬小定理可證明(因為p和q是質數)
n e·d ≡ n (mod p) 和 n e·d ≡ n (mod q)
這說明(因為p和q是不同的質數,所以p和q互質)
n e·d ≡ n (mod pq)
簽名消息
RSA也可以用來為一個消息署名。假如甲想給乙傳遞一個署名的消息的話,那么她可以為她的消息計算一個散列值(Message digest),然后用她的密鑰(private key)加密這個散列值并將這個“署名”加在消息的后面。這個消息只有用她的公鑰才能被解密。乙獲得這個消息后可以用甲的公鑰解密這個散列值,然后將這個數據與他自己為這個消息計算的散列值相比較。假如兩者相符的話,那么他就可以知道發信人持有甲的密鑰,以及這個消息在傳播路徑上沒有被篡改過。
編程實踐
在開始編程前,我們通過計算,來確定公鑰和密鑰。
計算公鑰和密鑰
假設p = 3、q = 17(p,q都是素數即可。),則N = pq = 51;
r = (p-1)(q-1) = (3-1)(17-1) = 32;
根據模反元素的計算公式,我們可以得出,e·d ≡ 1 (mod 32),即e·d = 32n+1 (n為正整數);我們假設n=1,則e·d = 33。e、d為正整數,并且e與r互質,則e = 3,d = 11。(兩個數交換一下也可以。)
到這里,公鑰和密鑰已經確定。公鑰為(N, e) = (51, 3),密鑰為(N, d) = (51, 11)。
編程實現
下面我們使用Java來實現一下加密和解密的過程。
public class rsademo { /** * 加密、解密算法 * @param key 公鑰或密鑰 * @param message 數據 * @return */ public static long rsa(int baseNum, int key, long message){ if(baseNum < 1 || key < 1){ return 0L; } //加密或者解密之后的數據 long rsaMessage = 0L; //加密核心算法 rsaMessage = Math.round(Math.pow(message, key)) % baseNum; return rsaMessage; } public static void main(String[] args){ //基數 int baseNum = 3 * 17; //公鑰 int keyE = 3; //密鑰 int keyD = 11; //未加密的數據 long msg = 28L; //加密后的數據 long encodeMsg = rsa(baseNum, keyE, msg); //解密后的數據 long decodeMsg = rsa(baseNum, keyD, encodeMsg); System.out.println("加密前:" + msg); System.out.println("加密后:" + encodeMsg); System.out.println("解密后:" + decodeMsg); } }
再計算一次;
p=61,q=53
p*q=3233; 3233寫成二進制是110010100001,一共有12位,密鑰是12位;
φ(n) = (p-1)(q-1)
φ(3233)=60×52=3120
隨機選擇一個整數e,條件是1< e < φ(n),且e與φ(n) 互質;
在1到3120之間,隨機選擇17;
計算e對于φ(n)的模反元素d;
已知 e=17, φ(n)=3120,
17x + 3120y = 1
這個方程可以用"擴展歐幾里得算法"求解;算出一組整數解為 (x,y)=(2753,-15),即 d=2753。
n=3233,e=17,d=2753,所以公鑰就是 (3233,17),私鑰就是(3233, 2753)。
RSA加密算法中,用到素數、互質數、指數運算、模運算等幾個數學知識。
素數
素數又稱質數,指在一個大于1的自然數中,除了1和此整數自身外,不能被其他自然數整除的數。
互質數
百度百科:公因數只有1的兩個數,叫做互質數。維基百科:互質,又稱互素。若N個整數的最大公因子是1,則稱這N個整數互質。
常見的互質數判斷方法主要有以下幾種:
兩個不同的質數一定是互質數。例如,2與7、13與19。
一個質數,另一個不為它的倍數,這兩個數為互質數。例如,3與10、5與 26。
相鄰的兩個自然數是互質數。如 15與 16。
相鄰的兩個奇數是互質數。如 49與 51。
較大數是質數的兩個數是互質數。如97與88。
小數是質數,大數不是小數的倍數的兩個數是互質數。例如 7和 16。
2和任何奇數是互質數。例如2和87。
1不是質數也不是合數,它和任何一個自然數在一起都是互質數。如1和9908。
輾轉相除法。
指數運算
指數運算又稱乘方計算,計算結果稱為冪。nm指將n自乘m次。把nm看作乘方的結果,叫做”n的m次冪”或”n的m次方”。其中,n稱為“底數”,m稱為“指數”。
模運算
模運算即求余運算?!澳!笔恰癕od”的音譯。和模運算緊密相關的一個概念是“同余”。數學上,當兩個整數除以同一個正整數,若得相同余數,則二整數同余。
兩個整數a,b,若它們除以正整數m所得的余數相等,則稱a,b對于模m同余,記作: a ≡ b (mod m);讀作:a同余于b模m,或者,a與b關于模m同余。例如:26 ≡ 14 (mod 12)。
RSA加密算法
公鑰與密鑰的產生
假設Alice想要通過一個不可靠的媒體接收Bob的一條私人訊息。她可以用以下的方式來產生一個公鑰和一個私鑰:
隨意選擇兩個大的質數p和q,p不等于q,計算N=pq。
根據歐拉函數,求得r = (p-1)(q-1)
選擇一個小于 r 的整數 e,求得 e 關于模 r 的模反元素,命名為d。(模反元素存在,當且僅當e與r互質)
將 p 和 q 的記錄銷毀。
(N,e)是公鑰,(N,d)是私鑰。Alice將她的公鑰(N,e)傳給Bob,而將她的私鑰(N,d)藏起來。
加密消息
假設Bob想給Alice送一個消息m,他知道Alice產生的N和e。他使用起先與Alice約好的格式將m轉換為一個小于N的整數n,比如他可以將每一個字轉換為這個字的Unicode碼,然后將這些數字連在一起組成一個數字。假如他的信息非常長的話,他可以將這個信息分為幾段,然后將每一段轉換為n。用下面這個公式他可以將n加密為c:
ne ≡ c (mod N)
計算c并不復雜。Bob算出c后就可以將它傳遞給Alice。
解密消息
Alice得到Bob的消息c后就可以利用她的密鑰d來解碼。她可以用以下這個公式來將c轉換為n:
cd ≡ n (mod N)
得到n后,她可以將原來的信息m重新復原。
解碼的原理是:
cd ≡ n e·d(mod N)
以及ed ≡ 1 (mod p-1)和ed ≡ 1 (mod q-1)。由費馬小定理可證明(因為p和q是質數)
n e·d ≡ n (mod p) 和 n e·d ≡ n (mod q)
這說明(因為p和q是不同的質數,所以p和q互質)
n e·d ≡ n (mod pq)
簽名消息
RSA也可以用來為一個消息署名。假如甲想給乙傳遞一個署名的消息的話,那么她可以為她的消息計算一個散列值(Message digest),然后用她的密鑰(private key)加密這個散列值并將這個“署名”加在消息的后面。這個消息只有用她的公鑰才能被解密。乙獲得這個消息后可以用甲的公鑰解密這個散列值,然后將這個數據與他自己為這個消息計算的散列值相比較。假如兩者相符的話,那么他就可以知道發信人持有甲的密鑰,以及這個消息在傳播路徑上沒有被篡改過。
編程實踐
在開始編程前,我們通過計算,來確定公鑰和密鑰。
計算公鑰和密鑰
假設p = 3、q = 17(p,q都是素數即可。),則N = pq = 51;
r = (p-1)(q-1) = (3-1)(17-1) = 32;
根據模反元素的計算公式,我們可以得出,e·d ≡ 1 (mod 32),即e·d = 32n+1 (n為正整數);我們假設n=1,則e·d = 33。e、d為正整數,并且e與r互質,則e = 3,d = 11。(兩個數交換一下也可以。)
到這里,公鑰和密鑰已經確定。公鑰為(N, e) = (51, 3),密鑰為(N, d) = (51, 11)。
編程實現
下面我們使用Java來實現一下加密和解密的過程。
public class rsademo { /** * 加密、解密算法 * @param key 公鑰或密鑰 * @param message 數據 * @return */ public static long rsa(int baseNum, int key, long message){ if(baseNum < 1 || key < 1){ return 0L; } //加密或者解密之后的數據 long rsaMessage = 0L; //加密核心算法 rsaMessage = Math.round(Math.pow(message, key)) % baseNum; return rsaMessage; } public static void main(String[] args){ //基數 int baseNum = 3 * 17; //公鑰 int keyE = 3; //密鑰 int keyD = 11; //未加密的數據 long msg = 28L; //加密后的數據 long encodeMsg = rsa(baseNum, keyE, msg); //解密后的數據 long decodeMsg = rsa(baseNum, keyD, encodeMsg); System.out.println("加密前:" + msg); System.out.println("加密后:" + encodeMsg); System.out.println("解密后:" + decodeMsg); } }
再計算一次;
p=61,q=53
p*q=3233; 3233寫成二進制是110010100001,一共有12位,密鑰是12位;
φ(n) = (p-1)(q-1)
φ(3233)=60×52=3120
隨機選擇一個整數e,條件是1< e < φ(n),且e與φ(n) 互質;
在1到3120之間,隨機選擇17;
計算e對于φ(n)的模反元素d;
已知 e=17, φ(n)=3120,
17x + 3120y = 1
這個方程可以用"擴展歐幾里得算法"求解;算出一組整數解為 (x,y)=(2753,-15),即 d=2753。
n=3233,e=17,d=2753,所以公鑰就是 (3233,17),私鑰就是(3233, 2753)。
從新帶入數字計算,看下,碉堡了;
以上程序和數字都是根據網上資料來的;不知哪兒錯了;等有空再搞吧;
看程序可知,對于要加密的數字m, m^e%N=c, c就是加密之后的密文。c^d%N=m, 就能解密得到m
總結
以上是生活随笔為你收集整理的RSA加密算法原理和java简单实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图解SqlServer更改sa密码
- 下一篇: 汇编排序算法代码总结