不再过多介绍, 依赖hutool库

加解密(hutool)

可通过new RSA()后获取密钥对(公钥、私钥);定义为常量。rsa.encrypt()加密得到byte[]

⚠:new String(byte[]);的方式导致输出乱码,致使后续解密ERROR;相关链接

通常通过 base64 对 byte[]进行编码;
然后通过rsa.decrypt() 对base64/byte[] 解密。

  1. import cn.hutool.core.codec.Base64;
  2. import cn.hutool.crypto.asymmetric.KeyType;
  3. import cn.hutool.crypto.asymmetric.RSA;
  4. public class RsaTest {
  5. private final static String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC05MBh04Wgw7S4xPn/PRo2QKFS70G4mkEzn5kibeN81Q/WuG4lJaWE6wW65hsFuz/DxRHvZaCeEO82ebr5LefYRzRXRzq6/a03e2wxiSA3DyFIcqySro+UpKDx824FfVIi+fs54Wc5xATThFKbfVD4UUA3hgAiq5sQpRpqq3CvTQIDAQAB";
  6. private final static String PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALTkwGHThaDDtLjE+f89GjZAoVLvQbiaQTOfmSJt43zVD9a4biUlpYTrBbrmGwW7P8PFEe9loJ4Q7zZ5uvkt59hHNFdHOrr9rTd7bDGJIDcPIUhyrJKuj5SkoPHzbgV9UiL5+znhZznEBNOEUpt9UPhRQDeGACKrmxClGmqrcK9NAgMBAAECgYBbfdNb5zsP+8wdI+t5z/LA++FcbAymjMZrkM5IHqJPkgfHx1JWUXstBh3I0Pdb58AxiSwwFAuvxsrml50cyL4YyK4owBXy0ZbQCnw6RXoAQnTsYoF+0kuaEEJ5n+ZP/IBcI0/a0Qlu4rgCtWXKCpCfes4znHOUSkUsrCoNWT5AYQJBAON1lJjX4OB80STbUedgSnrs5wMgi2W8lat0P895uNeGwavzyfD7hwv6CcJor+fd3fcZl4dZFHLhwzDv+zzn4KUCQQDLl2RjGGLLaUarvCf2LWT40B6ehykLSF639LoXqNRWZcbd90OSAr2lYj31CY0MptMeNrt3/2E3SKMptXLL+uuJAkBox8tyNVBEWXtGzTmHqpXk1qj8icttTFhuKRkUDHCX6F3jRmSqfFQTslU4l10hJNWRdNqW4PRIj7OJIaPMxMx5AkAgX3lZ/IWxHJNdOXUNQxicK9PCl3FiVuagz6xLmM/y0Qo3P1siO4dWZfG+Jf+ktF47nq5enWAi/0zak/ymDMcpAkBuEkAZFK2oG80YG0A5BNn1XSpXpJWJWg8TmPLCLBWjyMBD75pdX90MgqUEg4CqMHOIR23CKD/Ql5wjkR30ys/W";
  7. public static void main(String[] args) {
  8. RSA rsa = new RSA(PRIVATE_KEY, PUBLIC_KEY);
  9. byte[] encrypt = rsa.encrypt("username:password", KeyType.PublicKey);
  10. String base64 = Base64.encode(encrypt);
  11. System.out.println("base64 = " + base64);
  12. //new String(byte[]); 的方式导致输出乱码,且在解密时ERROR;
  13. //https://blog.csdn.net/qq_38022877/article/details/88560518
  14. //方式一、byte[] decrypt = rsa.decrypt(encrypt, KeyType.PrivateKey);
  15. //方式二、
  16. byte[] decrypt = rsa.decrypt(base64, KeyType.PrivateKey);
  17. String s1 = new String(decrypt);
  18. System.out.println("s1 = " + s1);
  19. }
  20. }

工具类(生成密钥对到文件)

  1. package utils;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.nio.file.Files;
  5. import java.security.*;
  6. import java.security.spec.InvalidKeySpecException;
  7. import java.security.spec.PKCS8EncodedKeySpec;
  8. import java.security.spec.X509EncodedKeySpec;
  9. import java.util.Base64;
  10. public class RsaUtils {
  11. private static final int DEFAULT_KEY_SIZE = 2048;
  12. /**
  13. * 从文件中读取公钥
  14. *
  15. * @param filename 公钥保存路径,相对于classpath
  16. * @return 公钥对象
  17. * @throws Exception
  18. */
  19. public static PublicKey getPublicKey(String filename) throws Exception {
  20. byte[] bytes = readFile(filename);
  21. return getPublicKey(bytes);
  22. }
  23. /**
  24. * 从文件中读取密钥
  25. *
  26. * @param filename 私钥保存路径,相对于classpath
  27. * @return 私钥对象
  28. * @throws Exception
  29. */
  30. public static PrivateKey getPrivateKey(String filename) throws Exception {
  31. byte[] bytes = readFile(filename);
  32. return getPrivateKey(bytes);
  33. }
  34. /**
  35. * 获取公钥
  36. *
  37. * @param bytes 公钥的字节形式
  38. * @return
  39. * @throws Exception
  40. */
  41. private static PublicKey getPublicKey(byte[] bytes) throws Exception {
  42. bytes = Base64.getDecoder().decode(bytes);
  43. X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes);
  44. KeyFactory factory = KeyFactory.getInstance("RSA");
  45. return factory.generatePublic(spec);
  46. }
  47. /**
  48. * 获取密钥
  49. *
  50. * @param bytes 私钥的字节形式
  51. * @return
  52. * @throws Exception
  53. */
  54. private static PrivateKey getPrivateKey(byte[] bytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
  55. bytes = Base64.getDecoder().decode(bytes);
  56. PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
  57. KeyFactory factory = KeyFactory.getInstance("RSA");
  58. return factory.generatePrivate(spec);
  59. }
  60. /**
  61. * 根据密文,生成rsa公钥和私钥,并写入指定文件
  62. *
  63. * @param publicKeyFilename 公钥文件路径
  64. * @param privateKeyFilename 私钥文件路径
  65. * @param secret 生成密钥的密文
  66. */
  67. public static void generateKey(String publicKeyFilename, String privateKeyFilename, String secret, int keySize) throws Exception {
  68. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
  69. SecureRandom secureRandom = new SecureRandom(secret.getBytes());
  70. keyPairGenerator.initialize(Math.max(keySize, DEFAULT_KEY_SIZE), secureRandom);
  71. KeyPair keyPair = keyPairGenerator.genKeyPair();
  72. // 获取公钥并写出
  73. byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
  74. publicKeyBytes = Base64.getEncoder().encode(publicKeyBytes);
  75. writeFile(publicKeyFilename, publicKeyBytes);
  76. // 获取私钥并写出
  77. byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
  78. privateKeyBytes = Base64.getEncoder().encode(privateKeyBytes);
  79. writeFile(privateKeyFilename, privateKeyBytes);
  80. }
  81. private static byte[] readFile(String fileName) throws Exception {
  82. return Files.readAllBytes(new File(fileName).toPath());
  83. }
  84. private static void writeFile(String destPath, byte[] bytes) throws IOException {
  85. File dest = new File(destPath);
  86. if (!dest.exists()) {
  87. dest.createNewFile();
  88. }
  89. Files.write(dest.toPath(), bytes);
  90. }
  91. }