介绍:

非对称加密相对与对称加密算法来说是高级的。
举个双保险的例子:

银行的保险柜,客户往银行的保险柜存贵重东西,这个保险柜的钥匙会有两把,客户有一把,银行有一把。如果想打开保险柜就需要银行的钥匙和客户的钥匙一块使用才能打开保险柜。

公钥,私钥:客户和银行的钥匙
公钥:是通过非安全的通道发放的,也就是说是公开的方式
私钥:自己保存的。

公钥和私钥一般是成对出现的,使用公钥加密的数据只有与它对应的私钥才能解开。
在非对称加密算法中有一些算法是可以公钥加密私钥解密,私钥加密公钥解密都支持的,有一些算法只支持一种方式的。

非对称加密算法种类:
DH(Diffie-Hellman):密钥交换算法
RSA:基于因子分解,既能用于数字加密也能用于数字签名
Elgamal:基于离散对数
ECC(Elliptical Curve Cryptography):椭圆曲线加密

DH

对称加密算法的弊端:
对称加密算法中公布密钥这个步骤会有问题,发送密钥的时候可能会出现泄露密钥的情况。一旦密钥被泄露,那么所有的数据就很容易被破解掉。

但是DH(密钥交换算法)是通过构建本地密钥来解决密钥容易在传递中泄露的问题的。

初始化发送方密钥涉及的三个类
1. KeyPairGenerator(通过KeyPairGenerator来得到KeyPair类的对象)

//创建KeyPairGenerator对象
KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");//"DH"指定算法的名称

2 KeyPair(得到密钥对,包括公钥和私钥)
3. PublicKey:公钥

初始化接收方密钥涉及到的类
1. KeyFactory:作用是生成密钥(包括公钥和私钥)
generatePublic()方法用来生成公钥
generatePrivate()方法用来生成私钥

2 X509EncodedKeySpec:根据ASN.1标准进行密钥编码
3. DHPublicKey:是PublicKey的某种具体的形式
4. DHParameterSpec:随从着DH算法来使用的参数的集合
5. KeyPairGenerator:通过KeyPairGenerator来得到KeyPair类的对象
6. PrivateKey:私钥

密钥构建涉及的类

  1. KeyAgreement:提供密钥一致性(或密钥交换)协议的功能
//生成实现指定密钥一致算法的KeyAgreement对象
static keyAgreement getInstance(String algorithm)
//为来自指定提供程序的指定密钥一致算法生成一个KeyAgreement对象
static keyAgreement getInstance(String algorithm,Provider provider)

2 SecretKey:生成一个分组的秘密密钥,同时提供了相应的类型安全的操作
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实现:public static void jdkDH() {try {/** 发送方的操作*/// 1.初始化发送方密钥KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");senderKeyPairGenerator.initialize(512);//设置长度KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();//生成keypair// 保存了发送方公钥的字节数组,发送给接收方(发送方式:网络、文件。。。)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("发送方和接收方密钥相同。");}else{System.out.println("发送方和接收方密钥不相同");}// 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();}}}

运行结果:

DH算法的应用场景

RSA

唯一广泛接受并实现的非对称加密的算法。
可以实现数据加密和数字签名。
提供了:
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实现:public static void jdkRSA() {try {// 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(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();}}}

运行结果:

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 world

RSA应用场景:

ElGamal

提供公钥加密算法。
基于离散对数。
JDK没有提供ElGamal算法的实现,是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”异常,是因为美国的出口限制,Sun通过权限文件(local_policy* .jar、US_export_policy.jar)做了相应限制。因此存在一些问题: 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 我的时java7,自己安装的。* /Library/Java/JavaVirtualMachines/jdk1.7.0_71* .jdk/Contents/Home/jre/lib/security目录下* ,对应覆盖local_policy.jar和US_export_policy.jar两个文件。* * 切换到%JDK_Home%\jre\lib\security目录下,对应覆盖local_policy.jar和US_export_policy.* jar两个文件。同时,你可能有必要在%JRE_Home%\lib\security目录下,也需要对应覆盖这两个文件。*/// BC实现:“私钥解密、公钥加密” , 对于:“私钥加密、公钥解密”有问题,因为Elgamal不支持public static void BCElgamal() {try {// 加入对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(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();}}}

运行结果:

应用场景:

非对称加密算法---加密学习笔记(四)相关推荐

  1. 对称加密算法---加密学习笔记(三)

    基本介绍 对称加密算法是现在应用范围最广,使用频率最高的加密算法. 对称的原因: 加密密钥 = 解密密钥,加密运算是解密运算的逆运算. 对称加密算法是初等的加密算法,从安全性上说,不是很高. 常用的对 ...

  2. 【http学习笔记四】安全篇

    [http学习笔记四]安全篇 文章目录 [http学习笔记四]安全篇 一.HTTPS 与 SSL/TLS ① 什么是安全? 机密性 完整性 身份认证 不可否认 ② 什么是HTTPS? ③ SSL/TL ...

  3. AES加密算法的学习笔记

    AES简介 高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的). 对称加密算法也就是加密和解密用相同的密钥 ...

  4. 深入浅出用户认证鉴权---使用非对称加密算法加密登录

    深入浅出用户认证鉴权 使用非对称加密算法加密登录 面临的问题 明文密码登录 MD5/BASE64 加密登录 解决方案 对称加密与非对称加密 对称加密 非对称加密 在登录过程中的使用 使用非对称加密算法 ...

  5. 数字签名算法---加密学习笔记(五)

    介绍 签名:就有安全性,抗否认性 数字签名:带有密钥(公钥,私钥)的消息摘要算法 作用: 1. 验证数据的完整性 2. 认证数据来源 3. 抗否认 数字签名遵循:私钥签名,公钥验证 常用的数字签名算法 ...

  6. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  7. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  8. RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决)

    RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决) 参考文章: (1)RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决) (2)https://www.cnblogs. ...

  9. JSP学习笔记(四十九):抛弃POI,使用iText生成Word文档

    POI操作excel的确很优秀,操作word的功能却不敢令人恭维.我们可以利用iText生成rtf文档,扩展名使用doc即可. 使用iText生成rtf,除了iText的包外,还需要额外的一个支持rt ...

最新文章

  1. Winform窗体应用程序的自动更新功能
  2. 人工智能是什么?带你一次掌握人工智能的三大重点及三大领域
  3. 央视深入报道,国内主流芯片真实水平如何?
  4. matlab 多条函数颜色渐变(没多大用处)
  5. fastadmin的基本用法 自动生成crud模块
  6. HDU 6249 Alice’s Stamps(dp)
  7. 关于Jeecg互联网化dubbo改造方案(下)
  8. 填写数独 洛谷P1784
  9. python3 range函数_为什么python3中的xrange函数不能用
  10. 由sock引起的感想
  11. wget下载的文件在哪里
  12. JDownloader 2 for Mac(不限速下载工具)
  13. 无线WiFi音视频传输,远距离WiFi技术方案,云望物联cv5200模组
  14. 工程学导论——心得体会
  15. quickchm乱码问题
  16. LNMP一键安装包如何重装Nginx
  17. js获取最近12个月
  18. 微信小程序开发(五) - 全局(app.js)逻辑 - js 文件
  19. 常见库爬取58二手全站信息
  20. python中 什么意思_请问python中%代表什么意思?

热门文章

  1. Echarts实现环形图的渐变颜色效果
  2. android 页面标题,Android v4包下的PagerTitleStrip,ViewPager的页面标题
  3. 在vue组件中使用vuex的state状态对象的5种方式
  4. js超出文字个数展示省略号
  5. springboot+sockjs进行消息推送(一对一模式)
  6. Morse理论:拓扑不变性特征匹配原理
  7. 在电脑桌面 右键点击 计算机,在桌面上右键点击电脑
  8. 构造函数可以实例化对象
  9. 李彦宏妻子马东敏向中国科大捐赠1亿 成立蔷薇基金
  10. for..in..遍历循环的简写模式