非对称加密算法--DH
11.1、非对称加密算法
特点:
- 发送方和接收方均有一个密钥对(公钥+私钥),其中公钥传播,私钥自己保存,不需要传播
- 私钥不需要传播的特性解决了对称加密算法中密钥传播的困难(这个困难一般通过线下传递可以解决)
- 加密安全性极高,只用于一些电子商务网站,加解密速度远低于对称加密
- 一般情况下,为了解决非对称加密算法加解密速度低的问题,采用非对称加密(使用公钥+私钥对对称加密的密钥进行加解密)+对称加密(加解密数据)相结合的方式。
常见算法:
- DH(非对称加密的基石)
- RSA(非对称加密的经典,除了可用于非对称加密,也可用于数字签名,RSA--155(512位密钥)已被破解)
- ElGamal
11.2、DH(仅能用于密钥分配,不能加解密数据)
实现方式:
- JDK(密钥长度:512~1024中的64的整数倍)
几个概念:
- 密钥对:公钥+私钥
- 本地密钥:对称加密的密钥
整个流程:
1)甲乙双方初始化各自的密钥对
甲方构建出密钥对keyPair1-->乙方使用甲方的密钥对中的公钥publicKey1构建出自己的密钥对keyPair2
2)甲乙双方构建各自的本地密钥
甲方使用自己的私钥privateKey1+乙方的公钥publicKey2构建出自己的本地密钥key1
乙方使用自己的私钥privateKey2+甲方的公钥publicKey1构建出自己的本地密钥key2
最后会发现key1==key2,这两个本地密钥将会是接下来对对称加密所使用的密钥
3)发送方(甲方或乙方均可)使用本地密钥+对称加密算法对待加密数据进行加密,传递给接收方
4)接收方使用本地密钥+对称加密算法对待解密数据进行解密

- 1 package com.util.dh;
- 2
- 3 import java.io.UnsupportedEncodingException;
- 4 import java.security.InvalidAlgorithmParameterException;
- 5 import java.security.InvalidKeyException;
- 6 import java.security.Key;
- 7 import java.security.KeyFactory;
- 8 import java.security.KeyPair;
- 9 import java.security.KeyPairGenerator;
- 10 import java.security.NoSuchAlgorithmException;
- 11 import java.security.PrivateKey;
- 12 import java.security.PublicKey;
- 13 import java.security.spec.InvalidKeySpecException;
- 14 import java.security.spec.PKCS8EncodedKeySpec;
- 15 import java.security.spec.X509EncodedKeySpec;
- 16
- 17 import javax.crypto.BadPaddingException;
- 18 import javax.crypto.Cipher;
- 19 import javax.crypto.IllegalBlockSizeException;
- 20 import javax.crypto.KeyAgreement;
- 21 import javax.crypto.NoSuchPaddingException;
- 22 import javax.crypto.interfaces.DHPublicKey;
- 23 import javax.crypto.spec.DHParameterSpec;
- 24 import javax.crypto.spec.SecretKeySpec;
- 25
- 26 import org.apache.commons.codec.binary.Base64;
- 27
- 28 /**
- 29 * 基于JDK的DH算法,工作模式采用ECB
- 30 */
- 31 public class DHJDK {
- 32 private static final String ENCODING = "UTF-8";
- 33 private static final String FDC_KEY_ALGORITHM = "DH";//非对称加密密钥算法
- 34 private static final String DC_KEY_ALGORITHM = "AES";//产生本地密钥的算法(对称加密密钥算法)
- 35 private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//加解密算法 格式:算法/工作模式/填充模式 注意:ECB不使用IV参数
- 36 private static final int FDC_KEY_SIZE = 512;//非对称密钥长度(512~1024之间的64的整数倍)
- 37
- 38 /**
- 39 * 生成甲方密钥对
- 40 */
- 41 public static KeyPair initKey() throws NoSuchAlgorithmException{
- 42 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(FDC_KEY_ALGORITHM);//密钥对生成器
- 43 keyPairGenerator.initialize(FDC_KEY_SIZE);//指定密钥长度
- 44 KeyPair keyPair = keyPairGenerator.generateKeyPair();//生成密钥对
- 45 return keyPair;
- 46 }
- 47
- 48 /**
- 49 * 生成乙方密钥对
- 50 * @param key 甲方公钥
- 51 */
- 52 public static KeyPair initKey(byte[] key) throws NoSuchAlgorithmException,
- 53 InvalidKeySpecException,
- 54 InvalidAlgorithmParameterException{
- 55 KeyFactory keyFactory = KeyFactory.getInstance(FDC_KEY_ALGORITHM);//密钥工厂
- 56 PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(key));//还原甲方公钥
- 57 DHParameterSpec dHParameterSpec = ((DHPublicKey)publicKey).getParams();
- 58
- 59 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyFactory.getAlgorithm());//乙方密钥对生成器
- 60 keyPairGenerator.initialize(dHParameterSpec);//使用甲方公钥参数初始化乙方密钥对生成器
- 61 KeyPair keyPair = keyPairGenerator.generateKeyPair();//生成密钥对
- 62 return keyPair;
- 63 }
- 64
- 65 /**
- 66 * DH加密
- 67 * @param data 带加密数据
- 68 * @param keyByte 本地密钥,由getSecretKey(byte[] publicKey, byte[] privateKey)产生
- 69 */
- 70 public static byte[] encrypt(String data, byte[] keyByte) throws NoSuchAlgorithmException,
- 71 NoSuchPaddingException,
- 72 InvalidKeyException,
- 73 IllegalBlockSizeException,
- 74 BadPaddingException,
- 75 UnsupportedEncodingException {
- 76 Key key = new SecretKeySpec(keyByte, DC_KEY_ALGORITHM);//生成本地密钥
- 77
- 78 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
- 79 cipher.init(Cipher.ENCRYPT_MODE, key);//设置加密模式并且初始化key
- 80 return cipher.doFinal(data.getBytes(ENCODING));
- 81 }
- 82
- 83 /**
- 84 * DH解密
- 85 * @param data 待解密数据为字节数组
- 86 * @param keyByte 本地密钥,由getSecretKey(byte[] publicKey, byte[] privateKey)产生
- 87 */
- 88 public static byte[] decrypt(byte[] data, byte[] keyByte) throws NoSuchAlgorithmException,
- 89 NoSuchPaddingException,
- 90 InvalidKeyException,
- 91 IllegalBlockSizeException,
- 92 BadPaddingException {
- 93 Key key = new SecretKeySpec(keyByte, DC_KEY_ALGORITHM);//生成本地密钥
- 94 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
- 95 cipher.init(Cipher.DECRYPT_MODE, key);
- 96 return cipher.doFinal(data);
- 97 }
- 98
- 99 /**
- 100 * 根据本方私钥与对方公钥构建本地密钥(即对称加密的密钥)
- 101 * @param publicKey 对方公钥
- 102 * @param privateKey 本方私钥
- 103 */
- 104 public static byte[] getSecretKey(byte[] publicKey, byte[] privateKey) throws NoSuchAlgorithmException,
- 105 InvalidKeySpecException,
- 106 InvalidKeyException{
- 107 KeyFactory keyFactory = KeyFactory.getInstance(FDC_KEY_ALGORITHM);//密钥工厂
- 108 PublicKey pubkey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKey));//还原公钥
- 109 PrivateKey prikey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKey));//还原私钥
- 110
- 111 KeyAgreement keyAgreement = KeyAgreement.getInstance(keyFactory.getAlgorithm());
- 112 keyAgreement.init(prikey);
- 113 keyAgreement.doPhase(pubkey, true);
- 114 return keyAgreement.generateSecret(DC_KEY_ALGORITHM).getEncoded();//生成本地密钥(对称加密的密钥)
- 115 }
- 116
- 117 /**
- 118 * 获取公钥
- 119 */
- 120 public static byte[] getPublicKey(KeyPair keyPair){
- 121 return keyPair.getPublic().getEncoded();
- 122 }
- 123
- 124 /**
- 125 * 获取私钥
- 126 */
- 127 public static byte[] getPrivateKey(KeyPair keyPair){
- 128 return keyPair.getPrivate().getEncoded();
- 129 }
- 130
- 131 /**
- 132 * 测试
- 133 */
- 134 public static void main(String[] args) throws NoSuchAlgorithmException,
- 135 InvalidKeySpecException,
- 136 InvalidAlgorithmParameterException,
- 137 InvalidKeyException,
- 138 NoSuchPaddingException,
- 139 IllegalBlockSizeException,
- 140 BadPaddingException,
- 141 UnsupportedEncodingException {
- 142 byte[] pubKey1;//甲方公钥
- 143 byte[] priKey1;//甲方私钥
- 144 byte[] key1;//甲方本地密钥
- 145 byte[] pubKey2;//乙方公钥
- 146 byte[] priKey2;//乙方私钥
- 147 byte[] key2;//乙方本地密钥
- 148
- 149 /*********************测试是否可以正确生成以上6个key,以及key1与key2是否相等*********************/
- 150 KeyPair keyPair1 = DHJDK.initKey();//生成甲方密钥对
- 151 pubKey1 = DHJDK.getPublicKey(keyPair1);
- 152 priKey1 = DHJDK.getPrivateKey(keyPair1);
- 153
- 154 KeyPair keyPair2 = DHJDK.initKey(pubKey1);//根据甲方公钥生成乙方密钥对
- 155 pubKey2 = DHJDK.getPublicKey(keyPair2);
- 156 priKey2 = DHJDK.getPrivateKey(keyPair2);
- 157
- 158 key1 = DHJDK.getSecretKey(pubKey2, priKey1);//使用对方公钥和自己私钥构建本地密钥
- 159 key2 = DHJDK.getSecretKey(pubKey1, priKey2);//使用对方公钥和自己私钥构建本地密钥
- 160
- 161 System.out.println("甲方公钥pubKey1-->"+Base64.encodeBase64String(pubKey1)+"@@pubKey1.length-->"+pubKey1.length);
- 162 System.out.println("甲方私钥priKey1-->"+Base64.encodeBase64String(priKey1)+"@@priKey1.length-->"+priKey1.length);
- 163 System.out.println("乙方公钥pubKey2-->"+Base64.encodeBase64String(pubKey2)+"@@pubKey2.length-->"+pubKey2.length);
- 164 System.out.println("乙方私钥priKey2-->"+Base64.encodeBase64String(priKey2)+"@@priKey2.length-->"+priKey2.length);
- 165 System.out.println("甲方密钥key1-->"+Base64.encodeBase64String(key1));
- 166 System.out.println("乙方密钥key2-->"+Base64.encodeBase64String(key2));
- 167
- 168 /*********************测试甲方使用本地密钥加密数据向乙方发送,乙方使用本地密钥解密数据*********************/
- 169 System.out.println("甲方-->乙方");
- 170 String data = "找一个好姑娘啊!";
- 171 byte[] encodeStr = DHJDK.encrypt(data, key1);
- 172 System.out.println("甲方加密后的数据-->"+Base64.encodeBase64String(encodeStr));
- 173 byte[] decodeStr = DHJDK.decrypt(encodeStr, key2);
- 174 System.out.println("乙方解密后的数据-->"+new String(decodeStr,"UTF-8"));
- 175
- 176 /*********************测试乙方使用本地密钥加密数据向甲方发送,甲方使用本地密钥解密数据*********************/
- 177 System.out.println("乙方-->甲方");
- 178 String data2 = "找一个好姑娘啊!";
- 179 byte[] encodeStr2 = DHJDK.encrypt(data2, key2);
- 180 System.out.println("乙方加密后的数据-->"+Base64.encodeBase64String(encodeStr2));
- 181 byte[] decodeStr2 = DHJDK.decrypt(encodeStr, key1);
- 182 System.out.println("甲方解密后的数据-->"+new String(decodeStr2,"UTF-8"));
- 183 }
- 184 }
非对称加密算法--DH的更多相关文章
- 第十一章 非对称加密算法--DH
注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第8章“高等加密算法--非对称加密算法” 11.1.非对称加密算法 特点: 发送方和接收方均有一个密钥对(公钥+私钥),其中公 ...
- 非对称加密算法DH
特点: 发送方和接收方均有一个密钥对(公钥+私钥),其中公钥传播,私钥自己保存,不需要传播 私钥不需要传播的特性解决了对称加密算法中密钥传播的困难(这个困难一般通过线下传递可以解决) 加密安全性极高, ...
- DH、RSA与ElGamal非对称加密算法实现及应用
1.对称加密与非对称加密概述 关于对称加密与非对称加密的概念这里不再多说,感兴趣可以看下我之前的几篇文章,下面说一说两者的主要区别. 对称加密算法数据安全,密钥管理复杂,密钥传递过程复杂,存在密钥泄露 ...
- 非对称加密算法-RSA
注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第8章“高等加密算法--非对称加密算法” 12.1.RSA(最经典的非对称加密算法) 特点: 使用一套密钥即可完成加解密(与D ...
- 信息加密之非对称加密算法RSA
前面为大家已经总结了,基于密钥交换的DH算法,现在就为大家再介绍一种基于因子分解的RSA算法,这种加密算法有两种实现形式:1.公钥加密,私钥解密:2.私钥加密,公钥解密.下面就为大家分析一下实现代码, ...
- 信息加密之非对称加密DH算法
非对称加密算法是相对于对称加密算法来说的,对于对称加密算法请查阅之前的总结,今天为大家介绍一下DH算法,DH是一种密钥交换算法,接收方根据发送方加密时的密钥,生成接收方解密密钥.下面就一起来学习一下吧 ...
- 第十二章 非对称加密算法-RSA
注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第8章“高等加密算法--非对称加密算法” 12.1.RSA(最经典的非对称加密算法) 特点: 使用一套密钥即可完成加解密(与D ...
- Java 加密解密 对称加密算法 非对称加密算法 MD5 BASE64 AES RSA
版权声明:本文为博主原创文章,未经博主允许不得转载. [前言] 本文简单的介绍了加密技术相关概念,最后总结了java中现有的加密技术以及使用方法和例子 [最简单的加密] 1.简单的概念 明文:加密前的 ...
- openssl 非对称加密算法RSA命令详解
1.非对称加密算法概述 非对称加密算法也称公开密钥算法,其解决了对称加密算法密钥分配的问题,非对称加密算法基本特点如下: 1.加密密钥和解密密钥不同 2.密钥对中的一个密钥可以公开 3.根据公开密钥很 ...
随机推荐
- android 获取设备拔插状态广播事件易漏掉的一行属性!
我们都知道设备拔插的状态获取需要一个权限 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILES ...
- 课堂 一些代码的叫法 JavaScript js
():圆括号 {} :花括号 <>:尖括号 [] :方括号
- [原]调试ComFriendlyWaitMtaThreadProc崩溃
项目里安装了UIA相关的钩子来监听UIA相关事件,退出的时候偶尔会崩溃在ComFriendlyWaitMtaThreadProc中,如下 从上图可以看出 是访问到无效的地址了,用!address 0 ...
- Git 命令清单
这份命令清单并不完善,后期会根据使用情况再进行更改. 操作分支项目 1 下载仓库的一个分支(baooab-patch-1)的代码 git clone -b baooab-patch-1 https:/ ...
- sharepoint 2013 开发环境安装
Sharepoint 介绍 Sharepoint 可以帮助企业用户轻松完成日常工作中诸如文档审批.在线申请等业务流程,同时提供多种接口实现后台业务系统的集成,它将 Office 桌面端应用的优势结合 ...
- 【Spring】简单的Spring MVC入门例子
前言 测试特性需要搭建一个简单的Spring MVC的例子,遂记录之,只是例子,只为入门者之示例. 版本说明 声明POM文件,指定需引入的JAR. <properties> <spr ...
- iOS的多版本配置(版本分离,多环境配置)
前几天公司说一个客户要搞一个app,我说搞呗,跟我啥关系...他说,就是从咱的app上搞,什么都一样,就是一些logo啥的不一样.我一开始感觉,那就改改logo呗,后来一想,凑,百度推送,友盟统计,B ...
- iOS_XCode7_Launch Image 的初使用
之前一直没有做笔记的习惯,后来发现很多知识不常用,容易忘了,再去网上找的,很浪费时间,现在尝试着自己写写博客,可以是自己笔记,方便以后查询,如果有纰漏,欢迎指正. 1.Xcode7中 ,assets. ...
- 1010. Radix (25)(未完成)
Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The an ...
- 一个简单确非常实用的javascript函数
在写js的时候,往往会碰到字符串拼接的问题,如果简单,直接使用+号连接字符串就可以了, 但是如果复杂,+用起来就非常不爽,在.net中有,Sting.Format函数,用起来还是很爽的,于是就想着js ...