公鑰私鑰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));