java加密算法非对称加密算法——数字信封 DH

类似数字签名,数字信封是这样描述的: 

数字信封 
        数字信封用加密技术来保证只有特定的收信人才能阅读信的内容。 
流程: 
    信息发送方采用对称密钥来加密信息,然后再用接收方的公钥来加密此对称密钥(这部分称为数字信封),再将它和信息一起发送给接收方;接收方先用相应的私钥打开数字信封,得到对称密钥,然后使用对称密钥再解开信息。

    接下来我们分析DH加密算法,一种适基于密钥一致协议的加密算法。 
DH 
Diffie- Hellman算法(D-H算法),密钥一致协议。是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。简单的说就是允许两名用 户在公开媒体上交换信息以生成"一致"的、可以共享的密钥。换句话说,就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私 钥)。以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。这样,在互通了本地密钥 (SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。不单 单是甲乙双方两方,可以扩展为多方共享数据通讯,这样就完成了网络交互数据的安全通讯!该算法源于中国的同余定理——中国馀数定理。  

流程分析: 

1.甲方构建密钥对儿,将公钥公布给乙方,将私钥保留;双方约定数据加密算法;乙方通过甲方公钥构建密钥对儿,将公钥公布给甲方,将私钥保留。 
2.甲方使用私钥、乙方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥加密数据,发送给乙方加密后的数据;乙方使用私钥、甲方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥对数据解密。 
3.乙方使用私钥、甲方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥加密数据,发送给甲方加密后的数据;甲方使用私钥、乙方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥对数据解密。 

  1.  

    各种Java加密算法
  2. 各种Java加密算法

  3. 各种Java加密算法


通过java代码实现如下:Coder类见

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
import  java.security.Key;
import  java.security.KeyFactory;
import  java.security.KeyPair;
import  java.security.KeyPairGenerator;
import  java.security.PublicKey;
import  java.security.spec.PKCS8EncodedKeySpec;
import  java.security.spec.X509EncodedKeySpec;
import  java.util.HashMap;
import  java.util.Map;
 
import  javax.crypto.Cipher;
import  javax.crypto.KeyAgreement;
import  javax.crypto.SecretKey;
import  javax.crypto.interfaces.DHPrivateKey;
import  javax.crypto.interfaces.DHPublicKey;
import  javax.crypto.spec.DHParameterSpec;
 
/**
  * DH安全编码组件
 
  * @author 梁栋
  * @version 1.0
  * @since 1.0
  */
public  abstract  class  DHCoder  extends  Coder {
     public  static  final  String ALGORITHM =  "DH" ;
 
     /**
      * 默认密钥字节数
     
      * <pre>
      * DH
      * Default Keysize 1024  
      * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive).
      * </pre>
      */
     private  static  final  int  KEY_SIZE =  1024 ;
 
     /**
      * DH加密下需要一种对称加密算法对数据加密,这里我们使用DES,也可以使用其他对称加密算法。
      */
     public  static  final  String SECRET_ALGORITHM =  "DES" ;
     private  static  final  String PUBLIC_KEY =  "DHPublicKey" ;
     private  static  final  String PRIVATE_KEY =  "DHPrivateKey" ;
 
     /**
      * 初始化甲方密钥
     
      * @return
      * @throws Exception
      */
     public  static  Map<String, Object> initKey()  throws  Exception {
         KeyPairGenerator keyPairGenerator = KeyPairGenerator
                 .getInstance(ALGORITHM);
         keyPairGenerator.initialize(KEY_SIZE);
 
         KeyPair keyPair = keyPairGenerator.generateKeyPair();
 
         // 甲方公钥
         DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic();
 
         // 甲方私钥
         DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate();
 
         Map<String, Object> keyMap =  new  HashMap<String, Object>( 2 );
 
         keyMap.put(PUBLIC_KEY, publicKey);
         keyMap.put(PRIVATE_KEY, privateKey);
         return  keyMap;
     }
 
     /**
      * 初始化乙方密钥
     
      * @param key
      *            甲方公钥
      * @return
      * @throws Exception
      */
     public  static  Map<String, Object> initKey(String key)  throws  Exception {
         // 解析甲方公钥
         byte [] keyBytes = decryptBASE64(key);
         X509EncodedKeySpec x509KeySpec =  new  X509EncodedKeySpec(keyBytes);
         KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
         PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
 
         // 由甲方公钥构建乙方密钥
         DHParameterSpec dhParamSpec = ((DHPublicKey) pubKey).getParams();
 
         KeyPairGenerator keyPairGenerator = KeyPairGenerator
                 .getInstance(keyFactory.getAlgorithm());
         keyPairGenerator.initialize(dhParamSpec);
 
         KeyPair keyPair = keyPairGenerator.generateKeyPair();
 
         // 乙方公钥
         DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic();
 
         // 乙方私钥
         DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate();
 
         Map<String, Object> keyMap =  new  HashMap<String, Object>( 2 );
 
         keyMap.put(PUBLIC_KEY, publicKey);
         keyMap.put(PRIVATE_KEY, privateKey);
 
         return  keyMap;
     }
 
     /**
      * 加密<br>
     
      * @param data
      *            待加密数据
      * @param publicKey
      *            甲方公钥
      * @param privateKey
      *            乙方私钥
      * @return
      * @throws Exception
      */
     public  static  byte [] encrypt( byte [] data, String publicKey,
             String privateKey)  throws  Exception {
 
         // 生成本地密钥
         SecretKey secretKey = getSecretKey(publicKey, privateKey);
 
         // 数据加密
         Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());
         cipher.init(Cipher.ENCRYPT_MODE, secretKey);
 
         return  cipher.doFinal(data);
     }
 
     /**
      * 解密<br>
     
      * @param data
      *            待解密数据
      * @param publicKey
      *            乙方公钥
      * @param privateKey
      *            乙方私钥
      * @return
      * @throws Exception
      */
     public  static  byte [] decrypt( byte [] data, String publicKey,
             String privateKey)  throws  Exception {
 
         // 生成本地密钥
         SecretKey secretKey = getSecretKey(publicKey, privateKey);
         // 数据解密
         Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());
         cipher.init(Cipher.DECRYPT_MODE, secretKey);
 
         return  cipher.doFinal(data);
     }
 
     /**
      * 构建密钥
     
      * @param publicKey
      *            公钥
      * @param privateKey
      *            私钥
      * @return
      * @throws Exception
      */
     private  static  SecretKey getSecretKey(String publicKey, String privateKey)
             throws  Exception {
         // 初始化公钥
         byte [] pubKeyBytes = decryptBASE64(publicKey);
 
         KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
         X509EncodedKeySpec x509KeySpec =  new  X509EncodedKeySpec(pubKeyBytes);
         PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
 
         // 初始化私钥
         byte [] priKeyBytes = decryptBASE64(privateKey);
 
         PKCS8EncodedKeySpec pkcs8KeySpec =  new  PKCS8EncodedKeySpec(priKeyBytes);
         Key priKey = keyFactory.generatePrivate(pkcs8KeySpec);
 
         KeyAgreement keyAgree = KeyAgreement.getInstance(keyFactory
                 .getAlgorithm());
         keyAgree.init(priKey);
         keyAgree.doPhase(pubKey,  true );
 
         // 生成本地密钥
         SecretKey secretKey = keyAgree.generateSecret(SECRET_ALGORITHM);
 
         return  secretKey;
     }
 
     /**
      * 取得私钥
     
      * @param keyMap
      * @return
      * @throws Exception
      */
     public  static  String getPrivateKey(Map<String, Object> keyMap)
             throws  Exception {
         Key key = (Key) keyMap.get(PRIVATE_KEY);
 
         return  encryptBASE64(key.getEncoded());
     }
 
     /**
      * 取得公钥
     
      * @param keyMap
      * @return
      * @throws Exception
      */
     public  static  String getPublicKey(Map<String, Object> keyMap)
             throws  Exception {
         Key key = (Key) keyMap.get(PUBLIC_KEY);
 
         return  encryptBASE64(key.getEncoded());
     }
}



再给出一个测试类:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import  static  org.junit.Assert.*;
 
import  java.util.Map;
 
import  org.junit.Test;
 
/**
 
  * @author 梁栋
  * @version 1.0
  * @since 1.0
  */
public  class  DHCoderTest {
 
     @Test
     public  void  test()  throws  Exception {
         // 生成甲方密钥对儿
         Map<String, Object> aKeyMap = DHCoder.initKey();
         String aPublicKey = DHCoder.getPublicKey(aKeyMap);
         String aPrivateKey = DHCoder.getPrivateKey(aKeyMap);
 
         System.err.println( "甲方公钥:\r"  + aPublicKey);
         System.err.println( "甲方私钥:\r"  + aPrivateKey);
         
         // 由甲方公钥产生本地密钥对儿
         Map<String, Object> bKeyMap = DHCoder.initKey(aPublicKey);
         String bPublicKey = DHCoder.getPublicKey(bKeyMap);
         String bPrivateKey = DHCoder.getPrivateKey(bKeyMap);
         
         System.err.println( "乙方公钥:\r"  + bPublicKey);
         System.err.println( "乙方私钥:\r"  + bPrivateKey);
         
         String aInput =  "abc " ;
         System.err.println( "原文: "  + aInput);
 
         // 由甲方公钥,乙方私钥构建密文
         byte [] aCode = DHCoder.encrypt(aInput.getBytes(), aPublicKey,
                 bPrivateKey);
 
         // 由乙方公钥,甲方私钥解密
         byte [] aDecode = DHCoder.decrypt(aCode, bPublicKey, aPrivateKey);
         String aOutput = ( new  String(aDecode));
 
         System.err.println( "解密: "  + aOutput);
 
         assertEquals(aInput, aOutput);
 
         System.err.println( " ===============反过来加密解密================== " );
         String bInput =  "def " ;
         System.err.println( "原文: "  + bInput);
 
         // 由乙方公钥,甲方私钥构建密文
         byte [] bCode = DHCoder.encrypt(bInput.getBytes(), bPublicKey,
                 aPrivateKey);
 
         // 由甲方公钥,乙方私钥解密
         byte [] bDecode = DHCoder.decrypt(bCode, aPublicKey, bPrivateKey);
         String bOutput = ( new  String(bDecode));
 
         System.err.println( "解密: "  + bOutput);
 
         assertEquals(bInput, bOutput);
     }
 
}



控制台输出:

甲方公钥:
MIHfMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHz
W5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSG
kx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgANDAAJAdAWBVmIzqcko
Ej6qFjLDL2+Y3FPq1iRbnOyOpDj71yKaK1K+FhTv04B0zy4DKcvAASV7/Gv0W+bgqdmffRkqrQ==

甲方私钥:
MIHRAgEAMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYX
rgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpD
TWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgAQyAjACJRfy1LyR
eHyD+4Hfb+xR0uoIGR1oL9i9Nk6g2AAuaDPgEVWHn+QXID13yL/uDos=

乙方公钥:
MIHfMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHz
W5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSG
kx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgANDAAJAVEYSfBA+I9nr
dWw3OBv475C+eBrWBBYqt0m6/eu4ptuDQHwV4MmUtKAC2wc2nNrdb1wmBhY1X8RnWkJ1XmdDbQ==

乙方私钥:
MIHSAgEAMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYX
rgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpD
TWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgAQzAjEAqaZiCdXp
2iNpdBlHRaO9ir70wo2n32xNlIzIX19VLSPCDdeUWkgRv4CEj/8k+/yd

原文: abc 
解密: abc 
 ===============反过来加密解密================== 
原文: def 
解密: def



如我所言,甲乙双方在获得对方公钥后可以对发送给对方的数据加密,同时也能对接收到的数据解密,达到了数据安全通信的目的!

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值