一、概述
非對稱加密算法概述,非對稱主要是相對於對稱加密算法而言的,對稱加密算法有一個密鑰和一個解鑰,非對稱算法有一個公鑰和一個私鑰,這兩個共同組成一個解鑰,才能實現解密。
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 = new X509EncodedKeySpec(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 = new X509EncodedKeySpec(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:" + new String(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 = new PKCS8EncodedKeySpec(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 = new X509EncodedKeySpec(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("私鑰加密、公鑰解密 ---- 解密:" + new String(result));// 4.公鑰加密、私鑰解密 ---- 加密X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(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 = new PKCS8EncodedKeySpec(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("公鑰加密、私鑰解密 ---- 解密:" + new String(result5));
四、Elgamal算法實現
ElGamal算法只提供了公鑰加密,私鑰解密形式,jdk中沒有實現,Bouncy Castle中對其進行了實現。
// 加入對BouncyCastle支持
Security.addProvider(new BouncyCastleProvider());// 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, new SecureRandom());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 = new X509EncodedKeySpec(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 = new PKCS8EncodedKeySpec(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 私鑰加密、公鑰解密 ---- 解密:" + new String(result5));