RSA加密算法
RSA加密算法簡史
RSA是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。當時他們?nèi)硕荚诼槭±砉W院工作。RSA就是他們?nèi)诵帐祥_頭字母拼在一起組成的。
公鑰與密鑰的產(chǎn)生
假設(shè)Alice想要通過一個不可靠的媒體接收Bob的一條私人訊息。她可以用以下的方式來產(chǎn)生一個公鑰和一個私鑰:
隨意選擇兩個大的質(zhì)數(shù)p和q,p不等于q,計算N=pq。
根據(jù)歐拉函數(shù),求得r = (p-1)(q-1)
選擇一個小于 r 的整數(shù) e,求得 e 關(guān)于模 r 的模反元素,命名為d。(模反元素存在,當且僅當e與r互質(zhì))
將 p 和 q 的記錄銷毀。
(N,e)是公鑰,(N,d)是私鑰。Alice將她的公鑰(N,e)傳給Bob,而將她的私鑰(N,d)藏起來。
加密消息
假設(shè)Bob想給Alice送一個消息m,他知道Alice產(chǎn)生的N和e。他使用起先與Alice約好的格式將m轉(zhuǎn)換為一個小于N的整數(shù)n,比如他可以將每一個字轉(zhuǎn)換為這個字的Unicode碼,然后將這些數(shù)字連在一起組成一個數(shù)字。假如他的信息非常長的話,他可以將這個信息分為幾段,然后將每一段轉(zhuǎn)換為n。用下面這個公式他可以將n加密為c:
ne ≡ c (mod N)
計算c并不復(fù)雜。Bob算出c后就可以將它傳遞給Alice。
解密消息
Alice得到Bob的消息c后就可以利用她的密鑰d來解碼。她可以用以下這個公式來將c轉(zhuǎn)換為n:
cd ≡ n (mod N)
得到n后,她可以將原來的信息m重新復(fù)原。
解碼的原理是:
cd ≡ n e·d(mod N)
以及ed ≡ 1 (mod p-1)和ed ≡ 1 (mod q-1)。由費馬小定理可證明(因為p和q是質(zhì)數(shù))
n e·d ≡ n (mod p) 和 n e·d ≡ n (mod q)
這說明(因為p和q是不同的質(zhì)數(shù),所以p和q互質(zhì))
n e·d ≡ n (mod pq)
簽名消息
RSA也可以用來為一個消息署名。假如甲想給乙傳遞一個署名的消息的話,那么她可以為她的消息計算一個散列值(Message digest),然后用她的密鑰(private key)加密這個散列值并將這個“署名”加在消息的后面。這個消息只有用她的公鑰才能被解密。乙獲得這個消息后可以用甲的公鑰解密這個散列值,然后將這個數(shù)據(jù)與他自己為這個消息計算的散列值相比較。假如兩者相符的話,那么他就可以知道發(fā)信人持有甲的密鑰,以及這個消息在傳播路徑上沒有被篡改過。
編程實踐
下面,開始我們的重點環(huán)節(jié):編程實踐。在開始編程前,我們通過計算,來確定公鑰和密鑰。
計算公鑰和密鑰
假設(shè)p = 3、q = 11(p,q都是素數(shù)即可。),則N = pq = 33;
r = (p-1)(q-1) = (3-1)(11-1) = 20;
根據(jù)模反元素的計算公式,我們可以得出,e·d ≡ 1 (mod 20),即e·d = 20n+1 (n為正整數(shù));我們假設(shè)n=1,則e·d = 21。e、d為正整數(shù),并且e與r互質(zhì),則e = 3,d = 7。(兩個數(shù)交換一下也可以。)
到這里,公鑰和密鑰已經(jīng)確定。公鑰為(N, e) = (33, 3),密鑰為(N, d) = (33, 7)。
編程實現(xiàn)
下面我們使用Java來實現(xiàn)一下加密和解密的過程。具體代碼如下:
RSA算法實現(xiàn):
?。踛ava] view plaincopy《span style=“font-size:14px;”》package security.rsa;
public class RSA {
/**
* 加密、解密算法
* @param key 公鑰或密鑰
* @param message 數(shù)據(jù)
* @return
*/
public static long rsa(int baseNum, int key, long message){
if(baseNum 《 1 || key 《 1){
return 0L;
}
//加密或者解密之后的數(shù)據(jù)
long rsaMessage = 0L;
//加密核心算法
rsaMessage = Math.round(Math.pow(message, key)) % baseNum;
return rsaMessage;
}
public static void main(String[] args){
//基數(shù)
int baseNum = 3 * 11;
//公鑰
int keyE = 3;
//密鑰
int keyD = 7;
//未加密的數(shù)據(jù)
long msg = 24L;
//加密后的數(shù)據(jù)
long encodeMsg = rsa(baseNum, keyE, msg);
//解密后的數(shù)據(jù)
long decodeMsg = rsa(baseNum, keyD, encodeMsg);
System.out.println(“加密前:” + msg);
System.out.println(“加密后:” + encodeMsg);
System.out.println(“解密后:” + decodeMsg);
}
《/span》
}
電子發(fā)燒友App
















評論