一、概述
非对称加密算法概述,非对称主要是相对于对称加密算法而言的,对称加密算法有一个密钥和一个解钥,非对称算法有一个公钥和一个私钥,这两个共同组成一个解钥,才能实现解密。
DH:密钥交换算法,算是非对称加密算法的起源。
RSA:基于因子分解,应用最广,RSA是可以双向加密的,私钥加密,公钥解密;公钥加密,私钥解密,是目前世界上使用最广的非对称加密算法。
ELGamal:基于离散对数。
ECC:椭圆曲线加密。
非对称加密算法:因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。非对称加密算法需要两个密钥:公开密钥和私有密钥。公开密钥与私有密钥是一对的。如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密。如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密(某些算法有提供)。非对称加密算法实现机密信息交换的基本过程是:甲方生成一对密钥并将其中的一把作为公用密钥向其它方公开,得到该公用密钥的乙方使用该密钥对信息进行加密后再发送给甲方。甲方再用自己保存的另一把专用密钥对加密后的信息进行解密。另一方面,甲方可以使用乙方提供的公钥对信息进行加密后再发送给乙方,乙方再用自己的私匙对数据进行解密。
二、DH算法概述
// 1.初始化发送方密钥KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");senderKeyPairGenerator.initialize(512); KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();//发送方公钥,发送给接收方(网络、文件……)byte[] senderPublicKeyEnc = senderKeyPair.getPublic().getEncoded();// 2.初始化接收方密钥KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH"); X509EncodedKeySpec x509EncodedKeySpec = newX509EncodedKeySpec(senderPublicKeyEnc); PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec); DHParameterSpec dhParameterSpec = ((DHPublicKey) receiverPublicKey).getParams(); KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH"); receiverKeyPairGenerator.initialize(dhParameterSpec); KeyPair receiverKeypair = receiverKeyPairGenerator.generateKeyPair(); PrivateKey receiverPrivateKey = receiverKeypair.getPrivate();byte[] receiverPublicKeyEnc = receiverKeypair.getPublic().getEncoded();// 3.密钥构建KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH"); receiverKeyAgreement.init(receiverPrivateKey); receiverKeyAgreement.doPhase(receiverPublicKey, true); SecretKey receiverDesKey = receiverKeyAgreement.generateSecret("DES"); KeyFactory senderKeyFactory = KeyFactory.getInstance("DH"); x509EncodedKeySpec = newX509EncodedKeySpec(receiverPublicKeyEnc); PublicKey senderPublicKey = senderKeyFactory.generatePublic(x509EncodedKeySpec); KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("DH"); senderKeyAgreement.init(senderKeyPair.getPrivate()); senderKeyAgreement.doPhase(senderPublicKey, true); SecretKey senderDesKey = senderKeyAgreement.generateSecret("DES");if(Objects.equals(receiverDesKey, senderDesKey)) { System.out.println("双方密钥相同。"); }// 4.加密Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);byte[] result = cipher.doFinal("Hellow".getBytes()); System.out.println("bc dh encrypt:"+ Base64.encodeBase64String(result));// 5.解密cipher.init(Cipher.DECRYPT_MODE, receiverDesKey); result = cipher.doFinal(result); System.out.println("bc dh decrypt:"+ newString(result));
三、RSA算法实现及应用
// 1.初始化发送方密钥
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(512); KeyPair keyPair = keyPairGenerator.generateKeyPair(); RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); System.out.println("Public Key:"+ Base64.encodeBase64String(rsaPublicKey.getEncoded())); System.out.println("Private Key:"+ Base64.encodeBase64String(rsaPrivateKey.getEncoded()));// 2.私钥加密、公钥解密----加密PKCS8EncodedKeySpec pkcs8EncodedKeySpec = newPKCS8EncodedKeySpec(rsaPrivateKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, privateKey);byte[] result = cipher.doFinal("hellow".getBytes()); System.out.println("私钥加密、公钥解密----加密:"+ Base64.encodeBase64String(result));// 3.私钥加密、公钥解密----解密X509EncodedKeySpec x509EncodedKeySpec = newX509EncodedKeySpec(rsaPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, publicKey); result = cipher.doFinal(result); System.out.println("私钥加密、公钥解密----解密:"+ newString(result));// 4.公钥加密、私钥解密----加密X509EncodedKeySpec x509EncodedKeySpec2 = newX509EncodedKeySpec(rsaPublicKey.getEncoded()); KeyFactory keyFactory2 = KeyFactory.getInstance("RSA"); PublicKey publicKey2 = keyFactory2.generatePublic(x509EncodedKeySpec2); Cipher cipher2 = Cipher.getInstance("RSA"); cipher2.init(Cipher.ENCRYPT_MODE, publicKey2);byte[] result2 = cipher2.doFinal("hellow".getBytes()); System.out.println("公钥加密、私钥解密----加密:"+ Base64.encodeBase64String(result2));// 5.私钥解密、公钥加密----解密PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = newPKCS8EncodedKeySpec(rsaPrivateKey.getEncoded()); KeyFactory keyFactory5 = KeyFactory.getInstance("RSA"); PrivateKey privateKey5 = keyFactory5.generatePrivate(pkcs8EncodedKeySpec5); Cipher cipher5 = Cipher.getInstance("RSA"); cipher5.init(Cipher.DECRYPT_MODE, privateKey5);byte[] result5 = cipher5.doFinal(result2); System.out.println("公钥加密、私钥解密----解密:"+ newString(result5));
四、Elgamal算法实现
ElGamal算法只提供了公钥加密,私钥解密形式,jdk中没有实现,Bouncy Castle中对其进行了实现。
//加入对BouncyCastle支持
Security.addProvider(newBouncyCastleProvider());// 1.初始化发送方密钥AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator.getInstance("Elgamal");//初始化参数生成器algorithmParameterGenerator.init(256);//生成算法参数AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters();//构建参数材料DHParameterSpec dhParameterSpec = (DHParameterSpec)algorithmParameters.getParameterSpec(DHParameterSpec.class);//实例化密钥生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Elgamal");//初始化密钥对生成器keyPairGenerator.initialize(dhParameterSpec, newSecureRandom());KeyPair keyPair = keyPairGenerator.generateKeyPair();//公钥PublicKey elGamalPublicKey = keyPair.getPublic();//私钥PrivateKey elGamalPrivateKey = keyPair.getPrivate(); System.out.println("Public Key:"+ Base64.encodeBase64String(elGamalPublicKey.getEncoded())); System.out.println("Private Key:"+ Base64.encodeBase64String(elGamalPrivateKey.getEncoded()));// 2.私钥解密、公钥加密----加密//初始化公钥//密钥材料转换X509EncodedKeySpec x509EncodedKeySpec2 = newX509EncodedKeySpec(elGamalPublicKey.getEncoded());//实例化密钥工厂KeyFactory keyFactory2 = KeyFactory.getInstance("Elgamal");//产生公钥PublicKey publicKey2 = keyFactory2.generatePublic(x509EncodedKeySpec2);//数据加密// Cipher cipher2 = Cipher.getInstance("Elgamal");Cipher cipher2 = Cipher.getInstance(keyFactory2.getAlgorithm()); cipher2.init(Cipher.ENCRYPT_MODE, publicKey2);byte[] result2 = cipher2.doFinal("hellow".getBytes()); System.out.println("私钥加密、公钥解密----加密:"+ Base64.encodeBase64String(result2));// 3.私钥解密、公钥加密----解密PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = newPKCS8EncodedKeySpec(elGamalPrivateKey.getEncoded()); KeyFactory keyFactory5 = KeyFactory.getInstance("Elgamal"); PrivateKey privateKey5 = keyFactory5.generatePrivate(pkcs8EncodedKeySpec5); Cipher cipher5 = Cipher.getInstance(keyFactory5.getAlgorithm()); cipher5.init(Cipher.DECRYPT_MODE, privateKey5);byte[] result5 = cipher5.doFinal(result2); System.out.println("Elgamal私钥加密、公钥解密----解密:"+ newString(result5));