Java加密与安全11-非对称加密算法
1. 密钥交换算法
2. 非对称加密算法
3. 概念
非对称加密就是加密和解密使用的不是相同的密钥:
只有同一个公钥 / 私钥对才能正常加密 / 解密
加密:用自己的私钥加密,然后发送给对方
encrypt(privateKeyA, message) -> encrypted
解密:对方用自己的公钥解密
decrypt(publicKeyA,encrypted) -> message
4. 非对称加密典型算法
RSA(Ron Rivest, Adi Shamir, Leonard Adleman)
【经典例子】
RSAKeyPair.java
import javax.crypto.Cipher;import java.security.*;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.Base64;public class RSAKeyPair {// 私钥:PrivateKey sk;// 公钥:PublicKey pk;// 生成公钥/私钥对:public RSAKeyPair() throws GeneralSecurityException {KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");kpGen.initialize(1024);KeyPair kp = kpGen.generateKeyPair();this.sk = kp.getPrivate();this.pk = kp.getPublic();}// 从已保存的字节中(例如:读取文件)恢复公钥/私钥:public RSAKeyPair(byte[] pk, byte[] sk) throws GeneralSecurityException{KeyFactory kf = KeyFactory.getInstance("RSA");X509EncodedKeySpec pkSpec = new X509EncodedKeySpec(pk);this.pk = kf.generatePublic(pkSpec);PKCS8EncodedKeySpec skSpec = new PKCS8EncodedKeySpec(sk);this.sk = kf.generatePrivate(skSpec);}// 把私钥导出为字节public byte[] getPrivateKey(){return this.sk.getEncoded();}// 把公钥导出为字节public byte[] getPublicKey(){return this.pk.getEncoded();}// 用公钥加密:public byte[] encrypt(byte[] message) throws GeneralSecurityException{Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, this.pk);return cipher.doFinal(message);}// 用私钥解密:public byte[] decrypt(byte[] input) throws GeneralSecurityException{Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, this.sk);return cipher.doFinal(input);}public static void main(String[] args) throws Exception{// 明文:byte[] plain = "Hello,使用RSA非对称加密算法对数据进行加密!".getBytes();// 创建公钥/私钥对:RSAKeyPair rsa = new RSAKeyPair();// 加密:byte[] encrypted = rsa.encrypt(plain);System.out.println("encrypted: " + Base64.getEncoder().encodeToString(encrypted));// 解密:byte[] decrypted = rsa.decrypt(encrypted);System.out.println("decrypted: " + new String(decrypted, "UTF-8"));// 保存公钥/私钥:byte[] pk = rsa.getPublicKey();byte[] sk = rsa.getPrivateKey();System.out.println("pk: " + Base64.getEncoder().encodeToString(pk));System.out.println("sk: " + Base64.getEncoder().encodeToString(sk));// 重新恢复公钥/私钥:RSAKeyPair rsa2 = new RSAKeyPair(pk, sk);// 加密:byte[] encrypted2 = rsa2.encrypt(plain);System.out.println("encrypted: " + Base64.getEncoder().encodeToString(encrypted2));// 解密:byte[] decrypted2 = rsa2.decrypt(encrypted2);System.out.println("decrypted: " + new String(decrypted2, "UTF-8"));}}
运行RSAKeyPair.java结果:
5. 非对称加密的优点
对称加密需要协商密钥,而非对称加密可以安全地公开各自的公钥
N个人之间通信:
使用非对称加密只需要N个密钥对,每个人只管理自己的密钥对
使用对称加密需要N*(N-1)/2个密钥,每个人需要管理N-1个密钥
6. 非对称加密的缺点
运算速度慢
7. 中间人攻击
8. 总结
非对称加密就是加密和解密使用的不是相同的密钥
只有同一个公钥/ 私钥对才能正常加密 / 解密
只使用非对称加密算法不能防止中间人攻击
