公鑰私鑰RSA加密
一、摘要
公鑰(Public Key)與私鑰(Private Key)是通過一種算法得到的一個密鑰對(即一個公鑰和一個私鑰),公鑰是密鑰對中公開的部分,私鑰則是非公開的部分。公鑰通常用於加密會話密鑰、驗證數字簽名,或加密可以用相應的私鑰解密的數據。通過這種算法得到的密鑰對能保證在世界范圍內是獨一的。使用這個密鑰對的時候,如果用其中一個密鑰加密一段數據,必須用另一個密鑰解密。比如用公鑰加密數據就必須用私鑰解密,如果用私鑰加密也必須用公鑰解密,否則解密將不會成功。
二、背景
網絡間雙方通信需要有一種加密方式,RSA公鑰加密是目前被推薦的加密標准。
三、推廣建議
RSA是目前最有影響力的公鑰加密算法,它能夠抵抗到目前為止已知的所有密碼攻擊。
RSA算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰。
四、正文
舉例:
比如有兩個用戶Alice和Bob,Alice想把一段明文通過雙鑰加密的技術發送給Bob,Bob有一對公鑰和私鑰,那么加密解密的過程如下:
Bob將他的公開密鑰傳送給Alice。
Alice用Bob的公開密鑰加密她的消息,然后傳送給Bob。
Bob用他的私人密鑰解密Alice的消息。
上面的過程可以用下圖表示,Alice使用Bob的公鑰進行加密,Bob用自己的私鑰進行解密。

例子和圖出自《網絡安全基礎 應用與標准第二版》
總結:公鑰和私鑰是成對的,它們互相解密。
公鑰加密,私鑰解密。
私鑰數字簽名,公鑰驗證。
/**
* 使用RSA私鑰加密數據
*
* @param pubKeyInByte
* 打包的byte[]形式私鑰
* @param data
* 要加密的數據
* @return 加密數據
*/
public static byte[] encryptByRSA1(byte[] privKeyInByte, byte[] data) {
try {
PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec(
privKeyInByte);
KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec);
Cipher cipher = Cipher.getInstance(mykeyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privKey);
return cipher.doFinal(data);
} catch (Exception e) {
return null;
}
}
/**
* 用RSA公鑰解密
*
* @param privKeyInByte
* 公鑰打包成byte[]形式
* @param data
* 要解密的數據
* @return 解密數據
*/
public static byte[] decryptByRSA1(byte[] pubKeyInByte, byte[] data) {
try {
KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(pubKeyInByte);
PublicKey pubKey = mykeyFactory.generatePublic(pub_spec);
Cipher cipher = Cipher.getInstance(mykeyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, pubKey);
return cipher.doFinal(data);
} catch (Exception e) {
return null;
}
}
/**
* 公鑰加密
* @param data 待加密數據
* @param key 密鑰
* @return byte[] 加密數據
* */
public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{
//實例化密鑰工廠
KeyFactory keyFactory=KeyFactory.getInstance("RSA");
//初始化公鑰
//密鑰材料轉換
X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key);
//產生公鑰
PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);
//數據加密
Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return cipher.doFinal(data);
}
/**
* 私鑰解密
* @param data 待解密數據
* @param key 密鑰
* @return byte[] 解密數據
* */
public static byte[] decryptByPrivateKey(byte[] data,byte[] key) throws Exception{
//取得私鑰
PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory=KeyFactory.getInstance("RSA");
//生成私鑰
PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec);
//數據解密
Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
//Java生成公鑰私鑰
//實例化密鑰生成器
KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
//初始化密鑰生成器
/**
* 密鑰長度,DH算法的默認密鑰長度是1024
* 密鑰長度必須是64的倍數,在512到65536位之間
* */
keyPairGenerator.initialize(1024);
//生成密鑰對
KeyPair keyPair=keyPairGenerator.generateKeyPair();
//甲方公鑰
RSAPublicKey publicKey=(RSAPublicKey) keyPair.getPublic();
System.out.println("系數:"+publicKey.getModulus()+" 加密指數:"+publicKey.getPublicExponent());
//甲方私鑰
RSAPrivateKey privateKey=(RSAPrivateKey) keyPair.getPrivate();
System.out.println("系數:"+privateKey.getModulus()+"解密指數:"+privateKey.getPrivateExponent());
System.out.println("公鑰:"+ Base64.encodeBase64String(publicKey));
System.out.println("私鑰:"+Base64.encodeBase64String(privateKey));
