Java加密解密之非对称加密

非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。使用公钥加密的,要使用私钥解密。反之,使用私钥加密的,要使用公钥解密。

和对称加密的区别是:
对称加密:加密和解密时使用的是同一个秘钥
非对称加密:加密和解密时使用的是不同的秘钥

非对称加密与对称加密相比,其安全性更好:对称加密的通信双方使用相同的秘钥,如果一方的秘钥遭泄露,那么整个通信就会被破解。而非对称加密使用一对秘钥,一个用来加密,一个用来解密,而且公钥是公开的,秘钥是自己保存的,不需要像对称加密那样在通信之前要先同步秘钥。
非对称加密的缺点是加密和解密花费时间长、速度慢,只适合对少量数据进行加密。

非对称加密中使用的主要算法有:RSA、DSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)等。

下面演示一个Java(1.8.0_144)使用RSA算法的非对称加密

  1. package com.security.cipher;

  2.  
  3. import java.security.Key;

  4. import java.security.KeyPair;

  5. import java.security.KeyPairGenerator;

  6. import java.security.NoSuchAlgorithmException;

  7. import java.security.PrivateKey;

  8. import java.security.PublicKey;

  9.  
  10. import javax.crypto.Cipher;

  11.  
  12. /**

  13. * 这里面的API里面有很多是调用getInstance方法,这个方法的参数有algorithm或者transformation

  14. * 一:algorithm:算法

  15. *

  16. * 二:transformation:有两种格式

  17. * 1:算法/模式/填充方式。如:DES/CBC/PKCS5Padding

  18. * 2:算法。 如:DES

  19. *

  20. * 其中,algorithm、transformation的值,不区分大小写

  21. *

  22. * Java加密解密官方参考文档:

  23. * https://docs.oracle.com/javase/8/docs/technotes/guides/security/index.html

  24. * https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html

  25. */

  26. public class CipherTest {

  27.  
  28. /*

  29. * 使用KeyPairGenerator生成密钥对KeyPair

  30. * KeyPair对象中有公钥、私钥

  31. *

  32. * 其中,KeyPairGenerator.getInstance(algorithm)支持的算法有:RSA、DSA

  33. * 全部支持的算法见官方文档

  34. * https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator

  35. *

  36. */

  37. public static KeyPair newKeyPair(String algorithm) throws NoSuchAlgorithmException {

  38. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);

  39. KeyPair keyPair = keyPairGenerator.generateKeyPair();

  40. return keyPair;

  41. }

  42.  
  43. /**

  44. * 加密,对字符串进行加密,返回结果为byte数组

  45. * 保存的时候,可以把byte数组进行base64编码成字符串,或者把byte数组转换成16进制的字符串

  46. *

  47. * 其中,transformation支持的全部算法见官方文档:

  48. * https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher

  49. */

  50. public static byte[] encrypt(String transformation, Key key, String password) throws Exception {

  51. Cipher cipher = Cipher.getInstance(transformation);

  52. //加密模式

  53. cipher.init(Cipher.ENCRYPT_MODE, key);

  54. return cipher.doFinal(password.getBytes());

  55. }

  56.  
  57. /**

  58. * 解密,返回结果为原始字符串

  59. *

  60. * 其中,transformation支持的全部算法见官方文档:

  61. * https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher

  62. */

  63. public static String decrypt(String transformation, Key key, byte[] data) throws Exception {

  64. Cipher cipher = Cipher.getInstance(transformation);

  65. //解密模式

  66. cipher.init(Cipher.DECRYPT_MODE, key);

  67. byte[] result = cipher.doFinal(data);

  68. String password = new String(result);

  69. return password;

  70. }

  71.  
  72. public static void main(String[] args) throws Exception {

  73. String password = "123456";

  74.  
  75. //这里指定的算法,必须是非对称加密算法

  76. String algorithm = "RSA";

  77. String transformation = algorithm;

  78.  
  79. //使用非对称加密,需要一对秘钥,这一对秘钥,可以从KeyPair对象中获取

  80. KeyPair keyPair = newKeyPair(algorithm);

  81.  
  82. //获取公钥

  83. PublicKey publicKey = keyPair.getPublic();

  84.  
  85. //获取私钥

  86. PrivateKey privateKey = keyPair.getPrivate();

  87.  
  88. //公钥加密私钥解密

  89. {

  90. //公钥加密

  91. byte[] passData = encrypt(transformation, publicKey, password);

  92. //私钥解密

  93. String pass = decrypt(transformation, privateKey, passData);

  94.  
  95. System.out.println("解密后的密码 : " + pass);

  96. }

  97.  
  98. //私钥加密公钥解密

  99. {

  100. //私钥加密

  101. byte[] passData = encrypt(transformation, privateKey, password);

  102. //公钥解密

  103. String pass = decrypt(transformation, publicKey, passData);

  104.  
  105. System.out.println("解密后的密码 : " + pass);

  106. }

  107. }

  108. }


可以看出,用法和对称加密差不多。关键是在于要有一个公钥,一个私钥。

上面的示例演示的是使用KeyPairGenerator、KeyPair对象获取公钥、私钥。除了这种方法,还有一个方法,就是使用keytool。下面将演示如何使用keytool获取公钥私钥

keytool -genkeypair -alias testkey -keyalg RSA -keystore test.jks -keypass 112233 -storetype jks -storepass 123456

输入命令之后,根据提示,输入对应的信息

这样,就可以得到一个test.jks的文件,这个文件中,就有公钥,私钥。获取方式如下:

  1. public static KeyPair newKeyPairByKeyStore(String path) throws Exception {

  2. KeyStore keyStore = KeyStore.getInstance("jks");

  3. String storePass = "123456";

  4.  
  5. try(InputStream input = new FileInputStream(path)) {

  6. keyStore.load(input, storePass.toCharArray());

  7. }

  8.  
  9. String keyPass = "112233";

  10. PrivateKey privateKey = (PrivateKey)keyStore.getKey("testkey", keyPass.toCharArray());

  11.  
  12. PublicKey publicKey = keyStore.getCertificate("testkey").getPublicKey();

  13.  
  14. return new KeyPair(publicKey, privateKey);

  15. }


同样的,使用openssl也可以

转自https://blog.csdn.net/mn960mn/article/details/78169213

猜你喜欢

转载自blog.csdn.net/sanyaoxu_2/article/details/81407452
今日推荐