本文共 7161 字,大约阅读时间需要 23 分钟。
一、概述 Diffie-Hellman算法(D-H算法),密钥一致协议。是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。简单的说就是允许两名用户在公开媒体上交换信息以生成"一致"的、可以共享的密钥。即就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥)。以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。这样,在互通了本地密钥(SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。 二、模型分析 1.甲方构建密钥对儿,将公钥公布给乙方,将私钥保留;双方约定数据加密算法;乙方通过甲方公钥构建密钥对儿,将公钥公布给甲方,将私钥保留。 2.甲方使用私钥、乙方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥加密数据,发送给乙方加密后的数据;乙方使用私钥、甲方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥对数据解密。 3.乙方使用私钥、甲方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥加密数据,发送给甲方加密后的数据;甲方使用私钥、乙方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥对数据解密。 实例: Java代码 复制代码 收藏代码 1.package cn.tzz.java.crypto.dh; 2. 3.import java.io.IOException; 4.import java.security.Key; 5.import java.security.KeyFactory; 6.import java.security.KeyPair; 7.import java.security.KeyPairGenerator; 8.import java.security.PublicKey; 9.import java.security.spec.PKCS8EncodedKeySpec; 10.import java.security.spec.X509EncodedKeySpec; 11.import java.util.HashMap; 12.import java.util.Map; 13. 14.import javax.crypto.Cipher; 15.import javax.crypto.KeyAgreement; 16.import javax.crypto.SecretKey; 17.import javax.crypto.interfaces.DHPrivateKey; 18.import javax.crypto.interfaces.DHPublicKey; 19.import javax.crypto.spec.DHParameterSpec; 20.import sun.misc.BASE64Decoder; 21.import sun.misc.BASE64Encoder; 22.import org.junit.Test; 23. 24. 25.public class DHUtil { 26. 27. public static final String ALGORITHM = "DH"; 28. /**默认密钥字节数*/ 29. private static final int KEY_SIZE = 1024; 30. 31. /** DH加密下需要一种对称加密算法对数据加密,这里我们使用DES,也可以使用其他对称加密算法*/ 32. public static final String SECRET_ALGORITHM = "DES"; 33. private static final String PUBLIC_KEY = "DHPublicKey";//公钥 34. private static final String PRIVATE_KEY = "DHPrivateKey";//私钥 35. 36. public String encryptBASE64(byte[] key) { 37. return (new BASE64Encoder()).encodeBuffer(key); 38. } 39. 40. public byte[] decryptBASE64(String key) throws IOException { 41. return new BASE64Decoder().decodeBuffer(key); 42. } 43. 44. /** 初始化甲方密钥 */ 45. public Map<String, Object> initKey() throws Exception { 46. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM); 47. keyPairGenerator.initialize(KEY_SIZE); 48. KeyPair keyPair = keyPairGenerator.generateKeyPair(); 49. // 甲方公钥 50. DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic(); 51. // 甲方私钥 52. DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate(); 53. Map<String, Object> keyMap = new HashMap<String, Object>(2); 54. keyMap.put(PUBLIC_KEY, publicKey); 55. keyMap.put(PRIVATE_KEY, privateKey); 56. return keyMap; 57. } 58. 59. /**初始化乙方密钥*/ 60. public Map<String, Object> initKey(String key) throws Exception { 61. // 解析甲方公钥 62. byte[] keyBytes = decryptBASE64(key); 63. X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); 64. KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); 65. PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); 66. // 由甲方公钥构建乙方密钥 67. DHParameterSpec dhParamSpec = ((DHPublicKey) pubKey).getParams(); 68. KeyPairGenerator keyPairGenerator = KeyPairGenerator 69. .getInstance(keyFactory.getAlgorithm()); 70. keyPairGenerator.initialize(dhParamSpec); 71. KeyPair keyPair = keyPairGenerator.generateKeyPair(); 72. // 乙方公钥 73. DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic(); 74. // 乙方私钥 75. DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate(); 76. Map<String, Object> keyMap = new HashMap<String, Object>(2); 77. keyMap.put(PUBLIC_KEY, publicKey); 78. keyMap.put(PRIVATE_KEY, privateKey); 79. 80. return keyMap; 81. } 82. 83. /** 84. * 加密<br> 85. * 86. * @param data 87. * 待加密数据 88. * @param publicKey 89. * 甲方公钥 90. * @param privateKey 91. * 乙方私钥 92. * @return 93. * @throws Exception 94. */ 95. public byte[] encrypt(byte[] data, String publicKey, String privateKey) throws Exception { 96. // 生成本地密钥 97. SecretKey secretKey = getSecretKey(publicKey, privateKey); 98. // 数据加密 99. Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm()); 100. cipher.init(Cipher.ENCRYPT_MODE, secretKey); 101. return cipher.doFinal(data); 102. } 103. 104. /** 105. * 解密<br> 106. * 107. * @param data 108. * 待解密数据 109. * @param publicKey 110. * 乙方公钥 111. * @param privateKey 112. * 乙方私钥 113. * @return 114. * @throws Exception 115. */ 116. public byte[] decrypt(byte[] data, String publicKey, String privateKey) throws Exception { 117. // 生成本地密钥 118. SecretKey secretKey = getSecretKey(publicKey, privateKey); 119. // 数据解密 120. Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm()); 121. cipher.init(Cipher.DECRYPT_MODE, secretKey); 122. return cipher.doFinal(data); 123. } 124. 125. /**构建密钥*/ 126. private SecretKey getSecretKey(String publicKey, String privateKey) throws Exception { 127. // 初始化公钥 128. byte[] pubKeyBytes = decryptBASE64(publicKey); 129. KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); 130. X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKeyBytes); 131. PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); 132. 133. // 初始化私钥 134. byte[] priKeyBytes = decryptBASE64(privateKey); 135. 136. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKeyBytes); 137. Key priKey = keyFactory.generatePrivate(pkcs8KeySpec); 138. 139. KeyAgreement keyAgree = KeyAgreement.getInstance(keyFactory 140. .getAlgorithm()); 141. keyAgree.init(priKey); 142. keyAgree.doPhase(pubKey, true); 143. 144. // 生成本地密钥 145. SecretKey secretKey = keyAgree.generateSecret(SECRET_ALGORITHM); 146. return secretKey; 147. } 148. 149. /** 取得私钥*/ 150. public String getPrivateKey(Map<String, Object> keyMap) throws Exception { 151. Key key = (Key) keyMap.get(PRIVATE_KEY); 152. return encryptBASE64(key.getEncoded()); 153. } 154. 155. /**取得公钥*/ 156. public String getPublicKey(Map<String, Object> keyMap) throws Exception { 157. Key key = (Key) keyMap.get(PUBLIC_KEY); 158. return encryptBASE64(key.getEncoded()); 159. } 160. 161. @Test 162. public void testDH() throws Exception { 163. // 生成甲方密钥对儿 164. Map<String, Object> aKeyMap = initKey(); 165. String aPublicKey = getPublicKey(aKeyMap); 166. String aPrivateKey = getPrivateKey(aKeyMap); 167. System.out.println("甲方公钥:\r" + aPublicKey); 168. System.out.println("甲方私钥:\r" + aPrivateKey); 169. 170. // 由甲方公钥产生本地密钥对儿 171. Map<String, Object> bKeyMap = initKey(aPublicKey); 172. String bPublicKey = getPublicKey(bKeyMap); 173. String bPrivateKey = getPrivateKey(bKeyMap); 174. System.out.println("乙方公钥:\r" + bPublicKey); 175. System.out.println("乙方私钥:\r" + bPrivateKey); 176. 177. String aInput = "abcdef "; 178. System.out.println("原文: " + aInput); 179. 180. // 由甲方公钥,乙方私钥构建密文 181. byte[] aCode = encrypt(aInput.getBytes(), aPublicKey, bPrivateKey); 182. 183. // 由乙方公钥,甲方私钥解密 184. byte[] aDecode = decrypt(aCode, bPublicKey, aPrivateKey); 185. String aOutput = (new String(aDecode)); 186. System.out.println("解密: " + aOutput); 187. 188. /**反过来加密解密*/ 189. String bInput = "123456 "; 190. System.out.println("原文: " + bInput); 191. 192. // 由乙方公钥,甲方私钥构建密文 193. byte[] bCode = encrypt(bInput.getBytes(), bPublicKey, aPrivateKey); 194. 195. // 由甲方公钥,乙方私钥解密 196. byte[] bDecode = decrypt(bCode, aPublicKey, bPrivateKey); 197. String bOutput = (new String(bDecode)); 198. System.out.println("解密: " + bOutput); 199. } 200. 201.}转载地址:http://vznoi.baihongyu.com/