package com.nova.sankuai.infra.utils;
|
|
import javax.crypto.Cipher;
|
|
import sun.misc.BASE64Decoder;
|
import sun.misc.BASE64Encoder;
|
|
import java.io.ByteArrayOutputStream;
|
import java.security.KeyFactory;
|
import java.security.KeyPair;
|
import java.security.KeyPairGenerator;
|
import java.security.SecureRandom;
|
import java.security.interfaces.RSAPrivateKey;
|
import java.security.interfaces.RSAPublicKey;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.X509EncodedKeySpec;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* Java RSA 加密工具类
|
* 参考: https://blog.csdn.net/qy20115549/article/details/83105736
|
*/
|
public class RSAUtils {
|
/**
|
* 密钥长度 于原文长度对应 以及越长速度越慢
|
*/
|
private final static int KEY_SIZE = 1024;
|
/**
|
* 用于封装随机产生的公钥与私钥
|
*/
|
private static Map<Integer, String> keyMap = new HashMap<>();
|
|
/** */
|
/**
|
* RSA最大加密明文大小
|
*/
|
private static final int MAX_ENCRYPT_BLOCK = 117;
|
|
/** */
|
/**
|
* RSA最大解密密文大小
|
*/
|
private static final int MAX_DECRYPT_BLOCK = 128;
|
|
/**
|
* 随机生成密钥对
|
*
|
* @throws Exception
|
*/
|
public static void genKeyPair() throws Exception {
|
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
|
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
|
// 初始化密钥对生成器
|
keyPairGen.initialize(KEY_SIZE, new SecureRandom());
|
// 生成一个密钥对,保存在keyPair中
|
KeyPair keyPair = keyPairGen.generateKeyPair();
|
// 得到私钥
|
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
// 得到公钥
|
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
String publicKeyString = encryptBASE64(publicKey.getEncoded());
|
// 得到私钥字符串
|
String privateKeyString = encryptBASE64(privateKey.getEncoded());
|
// 将公钥和私钥保存到Map
|
//0表示公钥
|
keyMap.put(0, publicKeyString);
|
//1表示私钥
|
keyMap.put(1, privateKeyString);
|
}
|
|
//编码返回字符串
|
public static String encryptBASE64(byte[] key) throws Exception {
|
return (new BASE64Encoder()).encodeBuffer(key);
|
}
|
|
//解码返回byte
|
public static byte[] decryptBASE64(String key) throws Exception {
|
return (new BASE64Decoder()).decodeBuffer(key);
|
}
|
|
/**
|
* RSA公钥加密
|
*
|
* @param str 加密字符串
|
* @param publicKey 公钥
|
* @return 密文
|
* @throws Exception 加密过程中的异常信息
|
*/
|
public static String encrypt(String str, String publicKey) throws Exception {
|
//base64编码的公钥
|
byte[] decoded = decryptBASE64(publicKey);
|
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
|
//RSA加密
|
Cipher cipher = Cipher.getInstance("RSA");
|
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
|
byte[] data = str.getBytes();
|
int inputLen = data.length;
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
int offSet = 0;
|
byte[] cache;
|
int i = 0;
|
// 对数据分段加密
|
while (inputLen - offSet > 0) {
|
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
} else {
|
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
}
|
out.write(cache, 0, cache.length);
|
i++;
|
offSet = i * MAX_ENCRYPT_BLOCK;
|
}
|
byte[] encryptedData = out.toByteArray();
|
out.close();
|
String outStr = encryptBASE64(encryptedData);
|
|
return outStr;
|
}
|
|
/**
|
* RSA私钥解密
|
*
|
* @param str 加密字符串
|
* @param privateKey 私钥
|
* @return 明文
|
* @throws Exception 解密过程中的异常信息
|
*/
|
public static String decrypt(String str, String privateKey) throws Exception {
|
//64位解码加密后的字符串
|
byte[] inputByte = decryptBASE64(str);
|
//base64编码的私钥
|
byte[] decoded = decryptBASE64(privateKey);
|
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
|
//RSA解密
|
Cipher cipher = Cipher.getInstance("RSA");
|
cipher.init(Cipher.DECRYPT_MODE, priKey);
|
int inputLen = inputByte.length;
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
int offSet = 0;
|
byte[] cache;
|
int i = 0;
|
// 对数据分段解密
|
while (inputLen - offSet > 0) {
|
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
cache = cipher.doFinal(inputByte, offSet, MAX_DECRYPT_BLOCK);
|
} else {
|
cache = cipher.doFinal(inputByte, offSet, inputLen - offSet);
|
}
|
out.write(cache, 0, cache.length);
|
i++;
|
offSet = i * MAX_DECRYPT_BLOCK;
|
}
|
String outStr = out.toString();
|
return outStr;
|
}
|
|
|
public static void main(String[] args) throws Exception {
|
long temp = System.currentTimeMillis();
|
//生成公钥和私钥
|
genKeyPair();
|
//加密字符串
|
// System.out.println("公钥:" + keyMap.get(0));
|
// System.out.println("私钥:" + keyMap.get(1));
|
// System.out.println("生成密钥消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
|
|
|
String message = "{\"reqBody\":[{\"age\":\"18\",\"annualIncome\":\"1\",\"businessLicense\":1,\"car\":1,\"corporateTax\":1,\"creditCard\":1,\"custName\":\"测试\",\"custRemark\":\"这仅仅只是一个测试\",\"dataFrom\":\"朋友圈测试\",\"education\":1,\"house\":1,\"insurancePolicy\":1,\"loanAmount\":100000.0,\"marryStatus\":1,\"microLoan\":1,\"onBehalfOf\":\"1\",\"phoneNum\":\"18612345678\",\"profession\":\"测试工\",\"providentFund\":1,\"sex\":1,\"socialSecurity\":1}]}";
|
System.out.println("原文:" + message);
|
|
temp = System.currentTimeMillis();
|
String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsDtrdQoBInH5227niqVTbSnzaLZOlBECMWbTpXGhTbdpCmap1qnvPojb3BcofuWIs+t3Uf0s2OlqhqrR+yuvB26e2uOgZsvhPQc69i3MwEH2vbr9oYYcuAlk9seCoPgUjFqwmTUQKg80DPJoKmtZDvMKvTQmRgtH8M8W75FyAzwIDAQAB";
|
System.out.println(pubKey);
|
String messageEn = encrypt(message, pubKey);
|
System.out.println("密文:" + messageEn);
|
System.out.println("加密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
|
|
temp = System.currentTimeMillis();
|
|
String priKey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKwO2t1CgEicfnbbueKpVNtKfNotk6UEQIxZtOlcaFNt2kKZqnWqe8+iNvcFyh+5Yiz63dR/SzY6WqGqtH7K68Hbp7a46Bmy+E9Bzr2LczAQfa9uv2hhhy4CWT2x4Kg+BSMWrCZNRAqDzQM8mgqa1kO8wq9NCZGC0fwzxbvkXIDPAgMBAAECgYEAqayYjzwGcBTL7gCvZmPgh8UELNBnWoM/+Gh6rOrxAt1BMQ6C+DigklkA5UezVOendn4KhoTlsduIBwflqWgJZuxfTsfj0+owrjpBJNO9uPiJrwFJ/moWuW3tIis9OH2mN2URfP8fg3OAJ4h5vqSBHAZfpFVeh4cd4mwFvnUGPBECQQDWxaZhn2KQH1gTzOkeUdlWMkqf4jUXgSnU0xg0RJ0gC3nvQGTn/8Wbh667wr1GpsK8CCXMmHh5ZUuXCiaUNqAHAkEAzRYlt9MlyuG1vjtxd6MDcvsTtIv1wOwh9F8YCI7x+ww00PSG6G98cwphnaso0JFvcQa8xRJjluqUF8hhK6PW+QJBAMKsbV/XpPOWNbPc7QF6l1G2TEYYOJ+RiGVM4oeeGf5N6Lyg1dYk1O1hU1UF86LyzVi62ehV2/3Nf3Ls1INL8EkCQQCXnaHwzlaIMGkt48A00/y+ykN9HGNoZqmLganA2fymvhVlzQDXYWQ9oBUefOTFnF8ozfRMNRYPAgjNtEOyAYPxAkB3fU5HEYWCjQPoQaBn0ZyP5s5V3df6uSlOo1tDgl08ZJfK0hm7nKd3/G1TFLSK4grZjhJj72fuy9c/ZT2rvKpi";
|
// messageEn = "V0JE7azjTQkXaQLuZcHAW+duFZdAjBUEdMNPt/9KN1hsqxO7l4Ueooao6XaiHPZvbAxNfnIXNkTv\n" +
|
// "xWVx19YWNRwNKy753EZW4HZzf2y/2NuR4Prj204UpDOpM6NdadkRHC7B1vkzRoWeviN46YWo9B1O\n" +
|
// "230mHC63SUeha3XEFk9aSuLpMwkYwk1JQlXKkOl9N44HBPueS5eqKuQ2XqcPXF5EuYMIk1ZpXAHI\n" +
|
// "BFNZnitKJok7MrxL1Kw5/gAMb3mFl4Ji/e7dZkXY5YO3WoyfAhKBSZUdEM1S/axRQrik4T0MQOZF\n" +
|
// "mO/P5YqoP5RyiSHyosiw7ubqag6UgbpYJuqImoEDh2uRbXkWrN8UOG28pN/VXQMvM01Sb5t/9XkJ\n" +
|
// "aM+eaxaEHwG7w531CbiKtm/2+WrU+Zv9evnHiE48OxwCx4AKpzYd4ZSBmzYMyaYKBSaTLyt+igBN\n" +
|
// "wtPjB6vmkWgXMhAO4rZNHQwigXX3nMrAzllf5pdHl8d3EspUgnvwcyYlW6u/qnOPjeQUEaefDrny\n" +
|
// "sKa3wDKKUSRr1dO90ADuZ5ctQMzT7uUJOAsizU2B/5XMJFJoZ3SZ41g8LcGiDsF3Jad4o/Fv9iQB\n" +
|
// "g0xN5VtanF4EG7GdYX47NyvxQzO4XA2CR7MEv3j2vEplFZAe55cRjUmUhFHxrWxO5by3FgpIPNs=";
|
String messageDe = decrypt(messageEn, priKey);
|
System.out.println("解密:" + messageDe);
|
System.out.println("解密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");;
|
}
|
}
|