非对称加密算法---加密学习笔记(四)
介紹:
非對稱加密相對與對稱加密算法來說是高級的。
舉個雙保險(xiǎn)的例子:
銀行的保險(xiǎn)柜,客戶往銀行的保險(xiǎn)柜存貴重東西,這個保險(xiǎn)柜的鑰匙會有兩把,客戶有一把,銀行有一把。如果想打開保險(xiǎn)柜就需要銀行的鑰匙和客戶的鑰匙一塊使用才能打開保險(xiǎn)柜。
公鑰,私鑰:客戶和銀行的鑰匙
公鑰:是通過非安全的通道發(fā)放的,也就是說是公開的方式
私鑰:自己保存的。
公鑰和私鑰一般是成對出現(xiàn)的,使用公鑰加密的數(shù)據(jù)只有與它對應(yīng)的私鑰才能解開。
在非對稱加密算法中有一些算法是可以公鑰加密私鑰解密,私鑰加密公鑰解密都支持的,有一些算法只支持一種方式的。
非對稱加密算法種類:
DH(Diffie-Hellman):密鑰交換算法
RSA:基于因子分解,既能用于數(shù)字加密也能用于數(shù)字簽名
Elgamal:基于離散對數(shù)
ECC(Elliptical Curve Cryptography):橢圓曲線加密
DH
對稱加密算法的弊端:
對稱加密算法中公布密鑰這個步驟會有問題,發(fā)送密鑰的時(shí)候可能會出現(xiàn)泄露密鑰的情況。一旦密鑰被泄露,那么所有的數(shù)據(jù)就很容易被破解掉。
但是DH(密鑰交換算法)是通過構(gòu)建本地密鑰來解決密鑰容易在傳遞中泄露的問題的。
初始化發(fā)送方密鑰涉及的三個類:
1. KeyPairGenerator(通過KeyPairGenerator來得到KeyPair類的對象)
2 KeyPair(得到密鑰對,包括公鑰和私鑰)
3. PublicKey:公鑰
初始化接收方密鑰涉及到的類:
1. KeyFactory:作用是生成密鑰(包括公鑰和私鑰)
generatePublic()方法用來生成公鑰
generatePrivate()方法用來生成私鑰
2 X509EncodedKeySpec:根據(jù)ASN.1標(biāo)準(zhǔn)進(jìn)行密鑰編碼
3. DHPublicKey:是PublicKey的某種具體的形式
4. DHParameterSpec:隨從著DH算法來使用的參數(shù)的集合
5. KeyPairGenerator:通過KeyPairGenerator來得到KeyPair類的對象
6. PrivateKey:私鑰
密鑰構(gòu)建涉及的類
2 SecretKey:生成一個分組的秘密密鑰,同時(shí)提供了相應(yīng)的類型安全的操作
3. KeyFactory
4. X509EncodedKeySpec
5. PublicKey
加解密涉及到的類:
Cipher
例子
package com.timliu.security.asymmetric_encryption;import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.X509EncodedKeySpec; import java.util.Objects;import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec;import org.apache.commons.codec.binary.Base64;public class DHTest {public static final String src = "hello world";public static void main(String[] args) {jdkDH();}// jdk實(shí)現(xiàn):public static void jdkDH() {try {/** 發(fā)送方的操作*/// 1.初始化發(fā)送方密鑰KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");senderKeyPairGenerator.initialize(512);//設(shè)置長度KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();//生成keypair// 保存了發(fā)送方公鑰的字節(jié)數(shù)組,發(fā)送給接收方(發(fā)送方式:網(wǎng)絡(luò)、文件。。。)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();//保存了接收方公鑰的字節(jié)數(shù)組,發(fā)送給發(fā)送方(發(fā)送方式:網(wǎng)絡(luò),文件。。。。)byte[] receiverPublicKeyEnc = receiverKeypair.getPublic().getEncoded();// 3.密鑰構(gòu)建KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");receiverKeyAgreement.init(receiverPrivateKey);receiverKeyAgreement.doPhase(receiverPublicKey, true);//生成接收方的本地密鑰SecretKey receiverDesKey = receiverKeyAgreement.generateSecret("DES");/** 發(fā)送方的操作*/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);//生成發(fā)送方的本地密鑰SecretKey senderDesKey = senderKeyAgreement.generateSecret("DES");if(Objects.equals(receiverDesKey, senderDesKey)){System.out.println("發(fā)送方和接收方密鑰相同。");}else{System.out.println("發(fā)送方和接收方密鑰不相同");}// 4.加密Cipher cipher = Cipher.getInstance("DES");cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);byte[] result = cipher.doFinal(src.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));} catch (Exception e) {e.printStackTrace();}}}運(yùn)行結(jié)果:
DH算法的應(yīng)用場景
RSA
唯一廣泛接受并實(shí)現(xiàn)的非對稱加密的算法。
可以實(shí)現(xiàn)數(shù)據(jù)加密和數(shù)字簽名。
提供了:
1. 公鑰加密,私鑰解密
2. 私鑰加密,公鑰解密
例子:
package com.timliu.security.asymmetric_encryption;import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher;import org.apache.commons.codec.binary.Base64;public class RSATest {public static final String src = "hello world";public static void main(String[] args) {jdkRSA();}// jdk實(shí)現(xiàn):public static void jdkRSA() {try {// 1.初始化發(fā)送方密鑰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(src.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(src.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));} catch (Exception e) {e.printStackTrace();}}}運(yùn)行結(jié)果:
Public Key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOz8ggiZp7ly13XoE9CtW3OlXQjVbrXc8zZCdKhFagXSSFcUvGqKbdfZuvjAjET7Vec7GurqLX14w99KnxFAbD8CAwEAAQ== Private Key: MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA7PyCCJmnuXLXdegT0K1bc6VdCNVutdzzNkJ0qEVqBdJIVxS8aopt19m6+MCMRPtV5zsa6uotfXjD30qfEUBsPwIDAQABAkAjp4nYyWVWnVSVRKlWh/5uU76/iXzyl59v1me+uVLONR7XjkQyz7Kq3uh33276FAxZtHFlabphCpZf0aqpUFuBAiEA9lAF2lMjx379oTtRJhs75iw11z7f+hpaxaUN+JMa1RECIQD2TpWxJfF20bRyDCi0U2sl2ElqdxjZe0pAAiebgr3sTwIgbEChQeHWUMBUMf9C2++ONMvrYc1FXMMmb8TpzfzBBzECIQCOB4y8JRQTHyO9bBOAwGWV4h2bneefaT/MnzF1tDOOcwIhALs3oH3XIAPBU2bFBaGqBTO//XIUoE8CfyOfPA3fvusC 私鑰加密、公鑰解密 ---- 加密: cIvL/HQH8gMBpD5qi99B4Cql/qZiNFc7eHfnua9qlQLGfQ436wNV9tzCQg+n7cR+/mDlAUSAvegwvk/0FD/Jmw== 私鑰加密、公鑰解密 ---- 解密:hello world 公鑰加密、私鑰解密 ---- 加密: rvG7tdyCbU5B4fbT2xrFPkH8tUUsepkpZwGALi56/CCpVWOyvGq/aqBS4dQJKxjwH0t0pfWzt+iw3fJe3qTwGg== 公鑰加密、私鑰解密 ---- 解密:hello worldRSA應(yīng)用場景:
ElGamal
提供公鑰加密算法。
基于離散對數(shù)。
JDK沒有提供ElGamal算法的實(shí)現(xiàn),是Bouncy Castle提供的。
例子:
package com.timliu.security.asymmetric_encryption;import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher; import javax.crypto.spec.DHParameterSpec;import org.apache.commons.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider;public class ElGamalTest {public static final String src = "hello world";public static void main(String[] args) {BCElgamal();}/*** * 對于:“Illegal key size or default* parameters”異常,是因?yàn)槊绹某隹谙拗?#xff0c;Sun通過權(quán)限文件(local_policy* .jar、US_export_policy.jar)做了相應(yīng)限制。因此存在一些問題: Java 6* 無政策限制文件:http://www.oracle* .com/technetwork/java/javase/downloads/jce-6-download-429243.html Java 7* 無政策限制文件* :http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download* -432124.html 我的時(shí)java7,自己安裝的。* /Library/Java/JavaVirtualMachines/jdk1.7.0_71* .jdk/Contents/Home/jre/lib/security目錄下* ,對應(yīng)覆蓋local_policy.jar和US_export_policy.jar兩個文件。* * 切換到%JDK_Home%\jre\lib\security目錄下,對應(yīng)覆蓋local_policy.jar和US_export_policy.* jar兩個文件。同時(shí),你可能有必要在%JRE_Home%\lib\security目錄下,也需要對應(yīng)覆蓋這兩個文件。*/// BC實(shí)現(xiàn):“私鑰解密、公鑰加密” , 對于:“私鑰加密、公鑰解密”有問題,因?yàn)镋lgamal不支持public static void BCElgamal() {try {// 加入對BouncyCastle支持Security.addProvider(new BouncyCastleProvider());// 1.初始化發(fā)送方密鑰AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator.getInstance("Elgamal");// 初始化參數(shù)生成器algorithmParameterGenerator.init(256);// 生成算法參數(shù)AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters();// 構(gòu)建參數(shù)材料DHParameterSpec dhParameterSpec = (DHParameterSpec) algorithmParameters.getParameterSpec(DHParameterSpec.class);// 實(shí)例化密鑰生成器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.私鑰解密、公鑰加密 ---- 加密// 初始化公鑰// 密鑰材料轉(zhuǎn)換X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(elGamalPublicKey.getEncoded());// 實(shí)例化密鑰工廠KeyFactory keyFactory2 = KeyFactory.getInstance("Elgamal");// 產(chǎn)生公鑰PublicKey publicKey2 = keyFactory2.generatePublic(x509EncodedKeySpec2);// 數(shù)據(jù)加密// Cipher cipher2 = Cipher.getInstance("Elgamal");Cipher cipher2 = Cipher.getInstance(keyFactory2.getAlgorithm());cipher2.init(Cipher.ENCRYPT_MODE, publicKey2);byte[] result2 = cipher2.doFinal(src.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("Elgamal");Cipher cipher5 = Cipher.getInstance(keyFactory5.getAlgorithm());cipher5.init(Cipher.DECRYPT_MODE, privateKey5);byte[] result5 = cipher5.doFinal(result2);System.out.println("Elgamal 私鑰加密、公鑰解密 ---- 解密:"+ new String(result5));} catch (Exception e) {e.printStackTrace();}}}運(yùn)行結(jié)果:
應(yīng)用場景:
總結(jié)
以上是生活随笔為你收集整理的非对称加密算法---加密学习笔记(四)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对称加密算法---加密学习笔记(三)
- 下一篇: Eclipse中Build Path的使