RSA非对称加密通常运用于对字符串进行加密,通过密钥对(公钥、私钥)实现加密。
通过生成的公钥,对字符串加密后,得到一个加密的字符串,将私钥与这个加密后的字符串进行解密,得到原先的字符串。
补充:如果加密的字符串过长(超过117个字节),会报错:javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 byte
1 package com.sdocean.security; 2 3 import org.apache.commons.codec.binary.Base64; 4 5 import javax.crypto.Cipher; 6 import java.security.*; 7 import java.security.interfaces.RSAPrivateKey; 8 import java.security.interfaces.RSAPublicKey; 9 import java.security.spec.PKCS8EncodedKeySpec; 10 import java.security.spec.X509EncodedKeySpec; 11 12 /** 13 * @ClassName RSAUtil 14 * @Description [一句话描述做什么] 15 * @Author wangdong 16 * @Date 2019/10/14 14:38 17 * @Version V1.0 18 **/ 19 public class RSAUtil { 20 21 public static String publicKey; // 公钥 22 public static String privateKey; // 私钥 23 24 /** 25 * 生成公钥和私钥 26 */ 27 public static void generateKey() { 28 // 1.初始化秘钥 29 KeyPairGenerator keyPairGenerator; 30 try { 31 keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 32 SecureRandom sr = new SecureRandom(); // 随机数生成器 33 keyPairGenerator.initialize(1024, sr); // 设置4096位长的秘钥 34 KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 开始创建 35 RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); 36 RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); 37 // 进行转码 38 publicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded()); 39 // 进行转码 40 privateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded()); 41 } catch (NoSuchAlgorithmException e) { 42 e.printStackTrace(); 43 } 44 } 45 46 /** 47 * 私钥匙加密或解密 48 * 49 * @param content 50 * @param privateKeyStr 51 * @return 52 */ 53 public static String encryptByprivateKey(String content, String privateKeyStr, int opmode) { 54 // 私钥要用PKCS8进行处理 55 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr)); 56 KeyFactory keyFactory; 57 PrivateKey privateKey; 58 Cipher cipher; 59 byte[] result; 60 String text = null; 61 try { 62 keyFactory = KeyFactory.getInstance("RSA"); 63 // 还原Key对象 64 privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); 65 cipher = Cipher.getInstance("RSA"); 66 cipher.init(opmode, privateKey); 67 //加密解密 68 text = encryptTxt(opmode,cipher,content); 69 } catch (Exception e) { 70 e.printStackTrace(); 71 } 72 return text; 73 } 74 75 public static String encryptTxt(int opmode, Cipher cipher, String content){ 76 byte[] result; 77 String text = null; 78 try{ 79 if (opmode == Cipher.ENCRYPT_MODE) { // 加密 80 result = cipher.doFinal(content.getBytes()); 81 text = Base64.encodeBase64String(result); 82 } else if (opmode == Cipher.DECRYPT_MODE) { // 解密 83 result = cipher.doFinal(Base64.decodeBase64(content)); 84 text = new String(result, "UTF-8"); 85 } 86 }catch (Exception e){ 87 e.printStackTrace(); 88 } 89 return text; 90 } 91 92 /** 93 * 公钥匙加密或解密 94 * 95 * @param content 96 * @return 97 */ 98 public static String encryptByPublicKey(String content, String publicKeyStr, int opmode) { 99 // 公钥要用X509进行处理 100 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr)); 101 KeyFactory keyFactory; 102 PublicKey publicKey; 103 Cipher cipher; 104 byte[] result; 105 String text = null; 106 try { 107 keyFactory = KeyFactory.getInstance("RSA"); 108 // 还原Key对象 109 publicKey = keyFactory.generatePublic(x509EncodedKeySpec); 110 cipher = Cipher.getInstance("RSA"); 111 cipher.init(opmode, publicKey); 112 text = encryptTxt(opmode,cipher,content); 113 } catch (Exception e) { 114 e.printStackTrace(); 115 } 116 return text; 117 } 118 119 public static void main(String[] args) { 120 // 1. 生成(公钥和私钥)密钥对 121 // RSAUtil.generateKey(); 122 // System.out.println("公钥:" + RSAUtil.publicKey); 123 // System.out.println("私钥:" + RSAUtil.privateKey); 124 System.out.println("----------公钥加密私钥解密(推荐),非对称加密,公钥保存在客户端,私钥保存在服务端-------------"); 125 String public_key="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCLgJDYvPYWrUfSDeTas8fKb8dBmKt6VNPBMz0KXVTlEMX+3XTv6lHarqspBp/WzX0gfDveKxJ3WnGuJt8jO0ivfOCodSxXc9tvZSC6fhAneAbUkFWiBOa1bMuit6zS7WiQs5draAW6vIRYWBCSZm7jV+HW9BpPYxiI1lpCD8Qd+wIDAQAB"; 126 // 使用 公钥加密,私钥解密 127 String textsr = "{\n" + 128 " \"base\":{\n" + 129 " \"uid\":12,\n" + 130 " \"name\":\"李四2\"\n" + 131 " },\n" + 132 " \"sex\":\"男\"\n" + 133 "}"; 134 String simi="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIuAkNi89hatR9IN5Nqzx8pvx0GY\r\n" + 135 "q3pU08EzPQpdVOUQxf7ddO/qUdquqykGn9bNfSB8O94rEndaca4m3yM7SK984Kh1LFdz229lILp+\r\n" + 136 "ECd4BtSQVaIE5rVsy6K3rNLtaJCzl2toBbq8hFhYEJJmbuNX4db0Gk9jGIjWWkIPxB37AgMBAAEC\r\n" + 137 "gYA7QYtFZU6q50QAp8I0W/VbugtLg8wjFHE2OcuN4YM0IeHYlr0bQ88tMtClhpjSp0qlR+AuSOF5\r\n" + 138 "LUPok75our/umKUsanT46Sepa/Wgh7vhh3oV5fqYA0J9lfdfqInJMCggavntcmHAEDjXbMJ8oMJS\r\n" + 139 "O2v9Tsc4nliLXaW0c/ulkQJBANuEQdzEFAYQPaxri1KZhDICWdLCqnPdda7roK7cYKO1H5akaVLn\r\n" + 140 "aS/DGMq00zpQiV8d9jWXqiYC2DKsUzYEuCUCQQCir/JJdJw+SBcAUSnS0/dZjbDB8mdkW2YafSwP\r\n" + 141 "rftrjHtnDEZoCZrccIv+V48aLXE4xIiHStS2cZRn278zDxOfAkBcryf75ZIqyTqxDStjMcxeLR3t\r\n" + 142 "3iGIEE57D6PlkMkA9h2jRkHuLiT8dJyIIfc5nP2TepwVHrdJm1PbeWUc3rs9AkBoAkrJUYcOfnJO\r\n" + 143 "HpW5lxB9LYwDAuG9FH37k2kXASlLQf4nDH76xqE+K6okyn/PwZuwKl4K+PlzRrwVhjUABLSLAkEA\r\n" + 144 "i87GLH9FV4Af4TMVt7UykSpmtU4BweqY0bQsRZdWnpdZtbmmMmUTB0+Eb1q5okVSgTktCtXECLda\r\n" + 145 "uy2IlrDGuw=="; 146 String encryptByPublic = RSAUtil.encryptByPublicKey(textsr, public_key, Cipher.ENCRYPT_MODE); 147 System.out.println("公钥加密:" + encryptByPublic); 148 String jiemi=RSAUtil.encryptByprivateKey(encryptByPublic, simi, Cipher.DECRYPT_MODE); 149 System.out.println("私钥解密:"+jiemi); 150 } 151 152 153 }
由于将密文字符串通过公钥生成的token放在浏览器上会有特殊字符的转码,所以要先将该token转换一下再放到url后面
1 String token=URLEncoder.encode("bBXUhaVgzbCzpwuA77MxQS1xV382YQUZDhqjwuenk8qHDv8Kvdgwh3Drh8D6jFA/44GyedrugKD0\r\n" + 2 "GaajnlUahJoxuwFt6OK0tSNWHNTAApwb7ZHf78B12BmZK0BK4LiA3Xm32YzAymdOyC5rWFpIAV6M\r\n" + 3 "Gn13TW737TpGIGDjzVg="); 4 System.out.println(token);