当前位置:   article > 正文

Java加密:四、非对称加密算法

Java加密:四、非对称加密算法

一、概述

          非对称加密算法与对称加密算法的主要差别在于非对称加密算法用于加密和解密的密钥不相同,一个公开,称为公钥;一个保密,称为私钥。因此,非对称密码算法也称为双钥或公钥加密算法。非对称加密算法解决了对称加密算法密钥分配问题,并极大地提高了算法安全性。多种B2C或B2B应用均使用非对称加密算法作为数据加密的核心算法。

        非对称加密算法源于DH算法(Diffie-Hellman,密钥交换算法),DH算法提出后,国际上相继出现了各种实用性更强的非对称加密算法,其构成主要是基于数学问题的求解,主要分为两类:

        1、基于因子分解难题。RSA算法是最为典型的非对称加密算法

        2、基于离散对数难题。ElGamal算法。

二、RSA

        RSA算法实现易于理解,对于RSA算法的测试只需要注意经公钥加密的数据是否可以通过私钥将其解密,反之,经私钥加密的数据是否可以通过公钥将其解密。

        就是说公钥和私钥都可用于加密和解密,但是应用场景有些区别。

        私钥签名,公钥验签,主要用于签名验签的业务场景。

        公钥加密,私钥解密,真正进行加密的业务场景。

        与DH算法不同,RSA算法仅需要一套密钥即可完成加密/解密操作,并且公钥的密钥长度明显小于私钥的密钥长度,更便于发送和携带。

        抽象类

  1. import org.apache.shiro.codec.Base64;
  2. import org.junit.Test;
  3. import javax.crypto.Cipher;
  4. import java.security.*;
  5. import java.security.interfaces.RSAPrivateKey;
  6. import java.security.interfaces.RSAPublicKey;
  7. import java.security.spec.PKCS8EncodedKeySpec;
  8. import java.security.spec.X509EncodedKeySpec;
  9. import java.util.HashMap;
  10. import java.util.Map;
  11. /***
  12. * RSA抽象类
  13. */
  14. public abstract class RSACoder {
  15. /**
  16. * 算法
  17. */
  18. public static final String KEY_ALGORITHM = "RSA";
  19. /**
  20. * 公钥
  21. */
  22. private static final String PUBLIC_KEY = "RSAPublicKey";
  23. /**
  24. * 私钥
  25. */
  26. private static final String PRIVATE_KEY = "RSAPrivateKey";
  27. /**
  28. * RSA密钥长度
  29. * 默认1024位
  30. * 密钥长度必须位64的倍数
  31. * 范围在512-65536之间
  32. */
  33. private static final int KEY_SIZE = 512;
  34. /**
  35. * 初始化密钥
  36. * @return 密钥Map
  37. */
  38. public static Map<String, Object> initKey()
  39. {
  40. try
  41. {
  42. // 实例化密钥对生成器
  43. KeyPairGenerator gen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
  44. // 初始化密钥对生成器
  45. gen.initialize(KEY_SIZE);
  46. // 生成密钥对
  47. KeyPair keyPair = gen.generateKeyPair();
  48. // 公钥
  49. RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
  50. // 私钥
  51. RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
  52. // 封装密钥
  53. Map<String, Object> map = new HashMap<String, Object>(2);
  54. map.put(PUBLIC_KEY, rsaPublicKey);
  55. map.put(PRIVATE_KEY, rsaPrivateKey);
  56. return map;
  57. }
  58. catch(Exception e)
  59. {
  60. }
  61. return null;
  62. }
  63. /**
  64. * 取得公钥
  65. * @param map
  66. * @return
  67. */
  68. public static byte[] getPublicKey(Map<String, Object> map)
  69. {
  70. Key key = (Key)map.get(PUBLIC_KEY);
  71. return key.getEncoded();
  72. }
  73. /**
  74. * 取得公钥
  75. * @param map
  76. * @return
  77. */
  78. public static byte[] getPrivateKey(Map<String, Object> map)
  79. {
  80. Key key = (Key)map.get(PRIVATE_KEY);
  81. return key.getEncoded();
  82. }
  83. /**
  84. * 私钥解密
  85. * @param data 待解密数据
  86. * @param key 私钥
  87. * @return byte[] 解密数据
  88. */
  89. public static byte[] decryptByPrivateKey(byte[] data, byte[] key)
  90. {
  91. try
  92. {
  93. //取得私钥
  94. PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(key);
  95. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  96. //生成私钥
  97. PrivateKey privateKey = keyFactory.generatePrivate(pkcs);
  98. //对数据解密
  99. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  100. cipher.init(Cipher.DECRYPT_MODE, privateKey);
  101. return cipher.doFinal(data);
  102. }
  103. catch(Exception e)
  104. {
  105. }
  106. return null;
  107. }
  108. /**
  109. * 公钥解密
  110. * @param data
  111. * @param key
  112. * @return
  113. */
  114. public static byte[] decryptByPublicKey(byte[] data, byte[] key)
  115. {
  116. try
  117. {
  118. //取得公钥
  119. X509EncodedKeySpec pkcs = new X509EncodedKeySpec(key);
  120. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  121. //生成公钥
  122. PublicKey publicKey = keyFactory.generatePublic(pkcs);
  123. //对数据解密
  124. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  125. cipher.init(Cipher.DECRYPT_MODE, publicKey);
  126. return cipher.doFinal(data);
  127. }
  128. catch(Exception e)
  129. {
  130. }
  131. return null;
  132. }
  133. /**
  134. * 公钥加密
  135. * @param data
  136. * @param key
  137. * @return
  138. */
  139. public static byte[] encryptByPublicKey(byte[] data, byte[] key)
  140. {
  141. try
  142. {
  143. //取得公钥
  144. X509EncodedKeySpec pkcs = new X509EncodedKeySpec(key);
  145. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  146. //生成公钥
  147. PublicKey publicKey = keyFactory.generatePublic(pkcs);
  148. //对数据加密
  149. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  150. cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  151. return cipher.doFinal(data);
  152. }
  153. catch(Exception e)
  154. {
  155. }
  156. return null;
  157. }
  158. /**
  159. * 私钥加密
  160. * @param data
  161. * @param key
  162. * @return
  163. */
  164. public static byte[] encryptByPrivateKey(byte[] data, byte[] key)
  165. {
  166. try
  167. {
  168. //取得私钥
  169. PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(key);
  170. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  171. //生成公钥
  172. PrivateKey privateKey = keyFactory.generatePrivate(pkcs);
  173. //对数据加密
  174. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  175. cipher.init(Cipher.ENCRYPT_MODE, privateKey);
  176. return cipher.doFinal(data);
  177. }
  178. catch(Exception e)
  179. {
  180. }
  181. return null;
  182. }
  183. }

         测试代码

  1. @Test
  2. public void digest_RSA()
  3. {
  4. byte[] publicKey;
  5. byte[] privateKey;
  6. try
  7. {
  8. Map<String, Object> map = RSACoder.initKey();
  9. publicKey = RSACoder.getPublicKey(map);
  10. privateKey = RSACoder.getPrivateKey(map);
  11. System.out.println("公钥;"+ org.apache.shiro.codec.Base64.encodeToString(publicKey));
  12. System.out.println("私钥;"+ org.apache.shiro.codec.Base64.encodeToString(privateKey));
  13. String input = "这是待加密的数据123456";
  14. byte[] data = input.getBytes();
  15. //私钥加密,公钥解密
  16. byte[] edata1 = RSACoder.encryptByPrivateKey(data, privateKey);
  17. System.out.println("私钥加密;"+ org.apache.shiro.codec.Base64.encodeToString(edata1));
  18. byte[] edata2 = RSACoder.decryptByPublicKey(edata1, publicKey);
  19. System.out.println("公钥解密;"+ new String(edata2));
  20. //公钥加密,私钥解密
  21. byte[] edata3 = RSACoder.encryptByPublicKey(data, publicKey);
  22. System.out.println("公钥加密;"+ org.apache.shiro.codec.Base64.encodeToString(edata3));
  23. byte[] edata4 = RSACoder.decryptByPrivateKey(edata3, privateKey);
  24. System.out.println("私钥解密;"+ new String(edata4));
  25. }
  26. catch(Exception e)
  27. {
  28. }
  29. }

        输出如下

 公钥;MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMgmYnp01ghihTnr0F3tHo4Q1HY0TDWr6CStK8HdnKYbnwA09TwQrmT7m0GPgU4Sieh7T0dqTT6oQvkCsVWD9y0CAwEAAQ==
私钥;MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAyCZienTWCGKFOevQXe0ejhDUdjRMNavoJK0rwd2cphufADT1PBCuZPubQY+BThKJ6HtPR2pNPqhC+QKxVYP3LQIDAQABAkBXE1wEqo/zVelgKZedRWvloqzMQDRnpUJ5sl03GpLsMJMcyGPFY9RvlYjMBdYOBqCb8PJtNtf1kHNuaMpSA3wBAiEA5uNuwy3m6mo+5mcJ4EKjkb5VOWinNFiQCMwaidUt+KkCIQDd6xvPq0H0pi0dtea5Sc+p/b6FpzoAE/1tCnZxGe1I5QIgQovgm766JGw07uFZ1lo+nL4YADDqqEqyUObK61kXI+kCIQDRveVyOIXE6c6YVxTzKNz56JZKkgwSiNIsXggly4BmNQIgEihE8cbNJCwcVxOBgYvIDMiaP6j8Pewmre3fXJZ4n7Y=

私钥加密;MCf+L8qCY05j1GLUkkGt65vj2JJg1wxSb2xgUQzwk+RvUQgZaFV4W4HNBKO3jIJ7t6cBz/1FUWlAkwaFBIl/SQ==
公钥解密;这是待加密的数据123456

公钥加密;n+vp/smgaUNzNG8kpc9BerCwa6pmIJUVYkTjRdGdjk7tXn3YEk3Rpa10gm4v5TDeNQ6y88n/cdiQ7D2l0Ox3aA==
私钥解密;这是待加密的数据123456

三、其它参考

        上面仅有关于RSA的用法。

Java非对称加密 - EZgod - 博客园非对称加密算法: DH: 实现方JDK Diffie-Hellman)密钥交换算法 非对称算法的基石 仅能用于密钥分配,不能用于加解密数据,一般加密数据用AES 密钥长度:512~1024中的64的整https://www.cnblogs.com/ezgod/p/14447405.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/898307
推荐阅读
相关标签
  

闽ICP备14008679号