在編程中,我們爲了保證數據安全,免不了要經常進行數據加密,於是產生了各種各樣的加密算法.無論怎樣,都還是存在被破解的風險.今天就來說說RSA算法.
背景
RSA公鑰加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美國麻省理工學院)開發的。RSA取名來自開發他們三者的名字。RSA是目前最有影響力的公鑰加密算法,它能夠抵抗到目前爲止已知的所有密碼攻擊,已被ISO推薦爲公鑰數據加密標準。RSA算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作爲加密密鑰。
雖然上面的解釋很深奧,但是你只要知道,這個算法非常安全就行了.
加密解密過程
假設有兩個用戶A,B. B在它的一側,生成了公鑰和私鑰,私鑰只有B自己知道,然後把公鑰分享給A,當然不僅是A,B的公鑰只要分享給了所有他信賴的人,那麼這些人都將能解密A的數據.
過程1:
A使用B的公鑰加密數據,然後B使用私鑰解密數據.這時所有擁有公鑰的用戶是不能解密數據的,因爲他們沒有私鑰.這個數據只有A和B能夠獲取,這就保證了數據的安全.
過程2:
B使用私鑰加密數據,那麼所有有公鑰的用戶都可以使用公要解密數據.其他沒有公鑰的人是沒有辦法獲取到數據的,這也保證了數據的安全性.
非對稱加密
通過上面的過程,我們可以看到這樣一個不同於以往加密算法的現象,那就是非對稱.什麼是非對稱?
你不能通過自己的加密密鑰,反向解密,這個過程是不可逆的,正是因爲如此才大大提高了它的安全性.公鑰和私鑰都可以進行加密解密,但他們必須配對使用.在私鑰被高度保護的情況下,永遠不會出現被破解的可能.
java實現
package com.mike;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
/**
* The class Rsa.java
*/
public class Rsa {
private static String PUBLIC_KEY_FILE = "C:\\my\\PublicKey";
private static String PRIVATE_KEY_FILE = "C:\\my\\PrivateKey";
/**
* 初始化密鑰
*
* @return
*/
public static void productKey() {
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair keyPair = keyGen.generateKeyPair();// 生成密鑰對
Key pubKey = keyPair.getPublic(); // 獲取公鑰
Key priKey = keyPair.getPrivate(); // 獲取私鑰
ObjectOutputStream oos1 = null;
ObjectOutputStream oos2 = null;
try {
/** 用對象流將生成的密鑰寫入文件 */
oos1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE));
oos2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE));
oos1.writeObject(pubKey);
oos2.writeObject(priKey);
} catch (Exception e) {
throw e;
} finally {
/** 清空緩存,關閉文件輸出流 */
oos1.close();
oos2.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 公鑰加密方法 私鑰加密也一樣
*
* @param source
* 源數據
* @return
* @throws Exception
*/
public static String encrypt(String source) throws Exception {
Key publicKey;
ObjectInputStream ois = null;
try {
/** 將文件中的公鑰對象讀出 */
ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
publicKey = (Key) ois.readObject();
} catch (Exception e) {
throw e;
} finally {
ois.close();
}
/** 得到Cipher對象來實現對源數據的RSA加密 */
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] b = source.getBytes();
/** 執行加密操作 */
byte[] b1 = cipher.doFinal(b);
return Base64.encodeBase64String(b1);
}
/**
* 私鑰解密算法 公鑰解密一樣
*
* @param cryptograph
* 密文
* @return
* @throws Exception
*/
public static String decrypt(String cryptograph) throws Exception {
Key privateKey;
ObjectInputStream ois = null;
try {
/** 將文件中的私鑰對象讀出 */
ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
privateKey = (Key) ois.readObject();
} catch (Exception e) {
throw e;
} finally {
ois.close();
}
/** 得到Cipher對象對已用公鑰加密的數據進行RSA解密 */
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] b1 = Base64.decodeBase64(cryptograph);
/** 執行解密操作 */
byte[] b = cipher.doFinal(b1);
return new String(b);
}
public static void main(String[] args) throws Exception {
Rsa.productKey();
String msg = "我是加密信息";
String encryt = Rsa.encrypt(msg);
System.out.println("加密後的字符:"+encryt);
System.out.println("解密後的字符:"+Rsa.decrypt(encryt));
}
}
這樣有了密鑰文件,你就可以進行加密和簽名了.歡迎公衆我的公衆號mike啥都想搞
,學習更多有趣的東西.