资讯专栏INFORMATION COLUMN

JAVA加密算法(4)- 非对称加密算法(DH,RSA)

Lucky_Boy / 1393人阅读

摘要:非对称密码概念发送者使用接收者的公钥加密,接收者使用自己的私钥解密。

非对称密码概念

</>复制代码

  1. 发送者使用接收者的公钥加密,接收者使用自己的私钥解密。

  2. 需要两个密钥进行加密或解密,分为公钥和私钥

  3. 特点:安全性高,速度慢

常用算法

DH密钥交换算法

RSA算法

ElGamal算法那

用途

密钥交换(DH)

</>复制代码

  1. 双方在没有确定共同密钥的情况下,生成密钥,不提供加密工作,加解密还需要其他对称加密算法实现

加密/解密(RSA)

数字签名(RSA)

DH算法示例

</>复制代码

  1. import javax.crypto.KeyAgreement;
  2. import javax.crypto.interfaces.DHPrivateKey;
  3. import javax.crypto.interfaces.DHPublicKey;
  4. import javax.crypto.spec.DHParameterSpec;
  5. import java.security.*;
  6. import java.security.spec.PKCS8EncodedKeySpec;
  7. import java.security.spec.X509EncodedKeySpec;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. //1 生成源密钥
  11. //2 把源公钥交给目标,目标通过源公钥,生成目标公钥和私钥
  12. //3 把目标公钥交给源
  13. //4 双方使用对方的公钥和和自己的私钥,生成本地密钥
  14. //5 如果双方生成本地密钥相同则完成密钥交换
  15. public class DHUtil {
  16. public static final String PUBLIC_KEY = "DH_Public_Key";
  17. public static final String PRIVATE_KEY = "DH_Private_key";
  18. /**
  19. * 生成源密钥对
  20. * @return
  21. * @throws Exception
  22. */
  23. public static Map initSourceKey() throws Exception{
  24. //创建KeyPairGenerator的实例,选用DH算法
  25. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
  26. //初始化密钥长度,默认1024,可选范围512-65536 & 64的倍数
  27. keyPairGenerator.initialize(1024);
  28. //生成密钥对
  29. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  30. DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
  31. DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
  32. //将密钥对放入Map
  33. Map keyMap = new HashMap();
  34. keyMap.put(PUBLIC_KEY, dhPublicKey);
  35. keyMap.put(PRIVATE_KEY, dhPrivateKey);
  36. return keyMap;
  37. }
  38. /**
  39. * 通过源公钥 生成 目标密钥对
  40. * @param sourcePublicKey
  41. * @return
  42. * @throws Exception
  43. */
  44. public static Map initTargetKey(byte[] sourcePublicKey) throws Exception {
  45. KeyFactory keyFactory = KeyFactory.getInstance("DH");
  46. //通过源公钥,生成keySpec,使用KeyFactory生成源PublicKey相关信息
  47. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(sourcePublicKey);
  48. DHPublicKey sourcePublic = (DHPublicKey) keyFactory.generatePublic(keySpec);
  49. DHParameterSpec dhPublicKeyParams = sourcePublic.getParams();
  50. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
  51. keyPairGenerator.initialize(dhPublicKeyParams);
  52. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  53. DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
  54. DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
  55. //将密钥对放入Map
  56. Map keyMap = new HashMap();
  57. keyMap.put(PUBLIC_KEY, dhPublicKey);
  58. keyMap.put(PRIVATE_KEY, dhPrivateKey);
  59. return keyMap;
  60. }
  61. /**
  62. * 使用一方的公钥和另一方的私钥,生成本地密钥
  63. * @return
  64. */
  65. public static byte[] generateLocalSecretKey(byte[] aPublicKey, byte[] bPrivateKey) throws Exception{
  66. KeyFactory keyFactory = KeyFactory.getInstance("DH");
  67. //通过A公钥,生成keySpec,使用KeyFactory生成A PublicKey相关信息
  68. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(aPublicKey);
  69. PublicKey publicKey = keyFactory.generatePublic(keySpec);
  70. //通过B私钥,生成B PrivateKey相关信息
  71. PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bPrivateKey);
  72. PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
  73. //通过KeyAgreement对A的PublicKey和B的PrivateKey进行加密
  74. KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
  75. keyAgreement.init(privateKey);
  76. keyAgreement.doPhase(publicKey,true);
  77. return keyAgreement.generateSecret("AES").getEncoded();//算法使用对称加密算法(DES,DESede,AES)
  78. //return keyAgreement.generateSecret(); // 也可以不选择算法,使用默认方法计算
  79. }
  80. //获取公钥字节数组
  81. public static byte[] getPublicKey(Map map){
  82. return ((DHPublicKey) map.get(PUBLIC_KEY)).getEncoded();
  83. }
  84. //获取私钥字节数组
  85. public static byte[] getPrivateKey(Map map){
  86. return ((DHPrivateKey) map.get(PRIVATE_KEY)).getEncoded();
  87. }
  88. public static void main(String[] args) throws Exception {
  89. byte[] source_public_key;
  90. byte[] source_private_key;
  91. byte[] source_local_key;
  92. byte[] target_public_key;
  93. byte[] target_private_key;
  94. byte[] target_local_key;
  95. Map sourceKey = initSourceKey();
  96. source_public_key = getPublicKey(sourceKey);
  97. source_private_key = getPrivateKey(sourceKey);
  98. System.out.println("源公钥:"+BytesToHex.fromBytesToHex(source_public_key));
  99. System.out.println("源私钥:"+BytesToHex.fromBytesToHex(source_private_key));
  100. Map targetKey = initTargetKey(getPublicKey(sourceKey));
  101. target_public_key = getPublicKey(targetKey);
  102. target_private_key = getPrivateKey(targetKey);
  103. System.out.println("目标公钥:"+BytesToHex.fromBytesToHex(target_public_key));
  104. System.out.println("目标私钥:"+BytesToHex.fromBytesToHex(target_private_key));
  105. source_local_key = generateLocalSecretKey(target_public_key, source_private_key);
  106. target_local_key = generateLocalSecretKey(source_public_key, target_private_key);
  107. System.out.println("源本地密钥:"+BytesToHex.fromBytesToHex(source_local_key));
  108. System.out.println("目标本地密钥:"+BytesToHex.fromBytesToHex(target_local_key));
  109. }
  110. }
RSA 加密/解密 示例

</>复制代码

  1. 公钥加密,私钥解密

</>复制代码

  1. import javax.crypto.Cipher;
  2. import java.security.KeyPair;
  3. import java.security.KeyPairGenerator;
  4. import java.security.PublicKey;
  5. import java.security.interfaces.RSAPrivateKey;
  6. import java.security.interfaces.RSAPublicKey;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9. /**
  10. * RSA加密工具
  11. */
  12. public class RSAUtil {
  13. public static final String PUBLIC_KEY = "RSA_Public_Key";
  14. public static final String PRIVATE_KEY = "RSA_Private_Key";
  15. /**
  16. * 初始化密钥
  17. * @return
  18. * @throws Exception
  19. */
  20. public static Map initKey() throws Exception{
  21. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
  22. keyPairGenerator.initialize(1024);//512-65536 & 64的倍数
  23. KeyPair keyPair = keyPairGenerator.generateKeyPair();
  24. RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  25. RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  26. Map keyMap = new HashMap();
  27. keyMap.put(PUBLIC_KEY, publicKey);
  28. keyMap.put(PRIVATE_KEY, privateKey);
  29. return keyMap;
  30. }
  31. public static RSAPublicKey getPublicKey(Map keyMap) {
  32. return (RSAPublicKey) keyMap.get(PUBLIC_KEY);
  33. }
  34. public static RSAPrivateKey getPrivateKey(Map keyMap){
  35. return (RSAPrivateKey) keyMap.get(PRIVATE_KEY);
  36. }
  37. /**
  38. * 使用公钥对数据进行加密
  39. * @param data
  40. * @param publicKey
  41. * @return
  42. * @throws Exception
  43. */
  44. public static byte[] encrypt(byte[] data, RSAPublicKey publicKey) throws Exception{
  45. Cipher cipher = Cipher.getInstance("RSA");
  46. cipher.init(Cipher.ENCRYPT_MODE,publicKey);
  47. return cipher.doFinal(data);
  48. }
  49. /**
  50. * 使用私钥解密
  51. * @param data
  52. * @param privateKey
  53. * @return
  54. * @throws Exception
  55. */
  56. public static byte[] decrypt(byte[] data, RSAPrivateKey privateKey) throws Exception{
  57. Cipher cipher = Cipher.getInstance("RSA");
  58. cipher.init(Cipher.DECRYPT_MODE,privateKey);
  59. return cipher.doFinal(data);
  60. }
  61. public static void main(String[] args) throws Exception {
  62. String data = "周杰伦-东风破";
  63. Map keyMap = initKey();
  64. byte[] miwen = encrypt(data.getBytes(),getPublicKey(keyMap));
  65. System.out.println("加密后的内容:"+BytesToHex.fromBytesToHex(miwen));
  66. byte[] plain = decrypt(miwen, getPrivateKey(keyMap));
  67. System.out.println("解密后的内容:"+new String(plain));
  68. }
  69. }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66233.html

相关文章

  • 慕课网_《Java实现对称加密》学习总结

    摘要:时间年月日星期三说明本文部分内容均来自慕课网。秘密密钥,生成一个分组的秘密密钥。 时间:2017年4月12日星期三说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:https://github.com/zccodere/s...个人学习源码:https://github.com/zccodere/s... 第一章:概述 1-1 概述 非对称...

    dailybird 评论0 收藏0
  • 没那么浅地谈谈HTTP与HTTPS【三】

    摘要:公开密钥加密的出现大大减轻了交换对称密钥的困难,公钥可以公开透过不安全可被窃听的渠道发送,用以加密明文。当与配合使用,称之为,与配合则称为,以此类推。这步没有签名,服务端收到数据后不会发现被篡改。对于认证机构,一旦私钥外泄,将可能导致整未济,亨。小狐汔济,濡其尾,无攸利。——《易》六、密钥管理当不再担心身份会被冒充、篡改之后,我们再来详细谈谈网络通信中对于加密算法的密钥管理。在密钥被签发后,...

    Tecode 评论0 收藏0
  • JAVA加密算法(1)- 密码学概述及BASE64算法使用

    密码学综述 密码学基本功能 机密性、鉴别、报文完整性、不可否认性 基本模型 sender-->加密算法 --> 密文 --> 解密算法 --> receiver 密钥源 密码学算法分类: 消息编码:Base64 消息摘要:MD类,SHA类,MAC 对称加密:DES,3DES,AES 非对称加密:RSA,DH密钥交换 数字签名:RSA signature,DSA signature 密码学...

    sevi_stuo 评论0 收藏0
  • Swoole 源码分析——Server模块之OpenSSL (上)

    摘要:另一方比如小明得到公钥之后,双方就可以通信。然而,中间人还是可能截获公钥,然后自己弄一对秘钥,然后告诉小明说是小红的公钥。这样,小亮在签署小红的身份证的时候,可以在小红身份证后面附上自己的身份证。一般来说,自签名的根身份证用于公司内部使用。 前言 自从 Lets Encrypt 上线之后,HTTPS 网站数量占比越来越高,相信不久的未来就可以实现全网 HTTPS,大部分主流浏览器也对 ...

    ky0ncheng 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<