package com.whyc.util;
|
|
import com.whyc.constant.YamlProperties;
|
import org.apache.commons.codec.binary.Base64;
|
|
import javax.crypto.Cipher;
|
import java.io.ByteArrayOutputStream;
|
import java.io.UnsupportedEncodingException;
|
import java.net.URLDecoder;
|
import java.security.*;
|
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.X509EncodedKeySpec;
|
import java.util.LinkedList;
|
import java.util.List;
|
|
/**
|
* 旧的加密采用的1024位的RSA秘钥对,
|
* 新的加密采用的3072位的RSA密钥对来加强安全
|
*/
|
public class RSAUtil {
|
|
/**
|
* 固定公私钥
|
*/
|
private static final String publicKeyOld = YamlProperties.publicKeyOld;
|
private static final String privateKeyOld = YamlProperties.privateKeyOld;
|
|
private static final String publicKey = YamlProperties.publicKey;
|
private static final String privateKey = YamlProperties.privateKey;
|
/**
|
* RSA最大加密明文大小
|
*/
|
private static final int MAX_ENCRYPT_BLOCK = 117;
|
/**
|
* RSA最大解密密文大小
|
*/
|
private static final int MAX_DECRYPT_BLOCK = 384;
|
|
public static final String fontSeparator = "&&&&&&&&&&";
|
/**
|
* 获取密钥对
|
*
|
* @return 密钥对
|
*/
|
public static List<String> getKeyPair() throws Exception {
|
LinkedList<String> list = new LinkedList<>();
|
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
|
generator.initialize(3072);
|
KeyPair keyPair = generator.generateKeyPair();
|
String publicKey = Base64.encodeBase64String(keyPair.getPublic().getEncoded());
|
String privateKey = Base64.encodeBase64String(keyPair.getPrivate().getEncoded());
|
System.out.println("公钥:"+publicKey);
|
System.out.println("私钥:"+privateKey);
|
list.add(publicKey);
|
list.add(privateKey);
|
return list;
|
}
|
/**
|
* 获取私钥
|
*
|
* @param privateKey 私钥字符串
|
* @return
|
*/
|
public static PrivateKey getPrivateKey(String privateKey) {
|
try {
|
KeyFactory keyFactory = null;
|
keyFactory = KeyFactory.getInstance("RSA");
|
|
byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
|
return keyFactory.generatePrivate(keySpec);
|
}catch (NoSuchAlgorithmException | InvalidKeySpecException e){
|
return null;
|
}
|
}
|
|
/**
|
* 获取私钥
|
*
|
* @return
|
*/
|
public static PrivateKey getPrivateKey() {
|
try {
|
KeyFactory keyFactory = null;
|
keyFactory = KeyFactory.getInstance("RSA");
|
|
byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
|
return keyFactory.generatePrivate(keySpec);
|
}catch (NoSuchAlgorithmException | InvalidKeySpecException e){
|
return null;
|
}
|
}
|
|
/**
|
* 获取私钥-旧版
|
*
|
* @return
|
*/
|
public static PrivateKey getPrivateKeyOld() {
|
try {
|
KeyFactory keyFactory = null;
|
keyFactory = KeyFactory.getInstance("RSA");
|
|
byte[] decodedKey = Base64.decodeBase64(privateKeyOld.getBytes());
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
|
return keyFactory.generatePrivate(keySpec);
|
}catch (NoSuchAlgorithmException | InvalidKeySpecException e){
|
return null;
|
}
|
}
|
|
/**
|
* 获取公钥
|
*
|
* @param publicKey 公钥字符串
|
* @return
|
*/
|
public static PublicKey getPublicKey(String publicKey) throws Exception {
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());
|
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
|
return keyFactory.generatePublic(keySpec);
|
}
|
|
/**
|
* 获取公钥
|
*
|
* @return
|
*/
|
public static PublicKey getPublicKey(){
|
try {
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());
|
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
|
return keyFactory.generatePublic(keySpec);
|
}catch (Exception e){
|
return null;
|
}
|
}
|
|
/**
|
* RSA加密
|
*
|
* @param data 待加密数据
|
* @param publicKey 公钥
|
* @return
|
*/
|
public static String encrypt(String data, PublicKey publicKey) {
|
try {
|
Cipher cipher = Cipher.getInstance("RSA");
|
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
int inputLen = data.getBytes().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.getBytes(), offset, MAX_ENCRYPT_BLOCK);
|
} else {
|
cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);
|
}
|
out.write(cache, 0, cache.length);
|
i++;
|
offset = i * MAX_ENCRYPT_BLOCK;
|
}
|
byte[] encryptedData = out.toByteArray();
|
out.close();
|
// 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串
|
// 加密后的字符串
|
return new String(Base64.encodeBase64String(encryptedData));
|
}catch (Exception e){
|
return null;
|
}
|
}
|
/**
|
* RSA解密
|
*
|
* @param data 待解密数据
|
* @param privateKey 私钥
|
* @return
|
*/
|
public static String decrypt(String data, PrivateKey privateKey) {
|
try {
|
Cipher cipher = Cipher.getInstance("RSA");
|
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
byte[] dataBytes = Base64.decodeBase64(data);
|
int inputLen = dataBytes.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(dataBytes, offset, MAX_DECRYPT_BLOCK);
|
} else {
|
cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
|
}
|
out.write(cache, 0, cache.length);
|
i++;
|
offset = i * MAX_DECRYPT_BLOCK;
|
}
|
byte[] decryptedData = out.toByteArray();
|
out.close();
|
// 解密后的内容
|
return new String(decryptedData, "UTF-8");
|
}catch (Exception e){
|
return null;
|
}
|
}
|
|
/**
|
* RSA解密
|
*
|
* @param data 待解密数据
|
* @return
|
*/
|
public static String decrypt(String data) {
|
try {
|
Cipher cipher = Cipher.getInstance("RSA");
|
cipher.init(Cipher.DECRYPT_MODE, getPrivateKey());
|
byte[] dataBytes = Base64.decodeBase64(data);
|
int inputLen = dataBytes.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(dataBytes, offset, MAX_DECRYPT_BLOCK);
|
} else {
|
cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
|
}
|
out.write(cache, 0, cache.length);
|
i++;
|
offset = i * MAX_DECRYPT_BLOCK;
|
}
|
byte[] decryptedData = out.toByteArray();
|
out.close();
|
// 解密后的内容
|
return new String(decryptedData, "UTF-8");
|
}catch (Exception e){
|
return null;
|
}
|
}
|
|
/**
|
* 前端加密数据RSA[明文+MD5(明文)]解密为明文和MD5[明文]
|
* @param frontEncryptData
|
* @return
|
*/
|
public static String[] decryptFront(String frontEncryptData,String separatorStr){
|
String[] dataArr = new String[2];
|
String dataMD5Mix = RSAUtil.decrypt(frontEncryptData, RSAUtil.getPrivateKey());
|
int index = dataMD5Mix.lastIndexOf(separatorStr);
|
String data = dataMD5Mix.substring(0, index);
|
String dataMD5 = dataMD5Mix.substring(index+separatorStr.length());
|
dataArr[0] = data;
|
dataArr[1] = dataMD5;
|
return dataArr;
|
}
|
|
/**
|
* 先URL解码,再进行密文解析[rsa(明文+md5)]
|
*/
|
public static String[] decryptFrontP(String frontEncryptData,String separatorStr){
|
/*try {
|
frontEncryptData = URLDecoder.decode(frontEncryptData, "utf-8");
|
} catch (UnsupportedEncodingException e) {
|
e.printStackTrace();
|
}*/
|
String[] dataArr = new String[2];
|
String dataMD5Mix = RSAUtil.decrypt(frontEncryptData, RSAUtil.getPrivateKey());
|
int index = dataMD5Mix.lastIndexOf(separatorStr);
|
String data = dataMD5Mix.substring(0, index);
|
String dataMD5 = dataMD5Mix.substring(index+separatorStr.length());
|
dataArr[0] = data;
|
dataArr[1] = dataMD5;
|
return dataArr;
|
}
|
|
public static void main(String[] args) throws Exception {
|
try {
|
String word = "9Lu6HgEvttjj8vYhy3ID+PqPbumuXhcH";
|
String encryptWord = encrypt(word, getPublicKey());
|
System.out.println(encryptWord);
|
|
/* String encryptWord = "X9rYw0Za1T7vgFO9cEMghH8f+Uo1Dhc3jAnMPpaKnCXL8nJ5xqueQ7Pldp0GmOr3imulIqxIQjdwZ43trz6s9YDi9lpEDNGVHQAx6hazHQmSnQ04HrPRn6xn9hvYo6BaJQYf+Jw5SmYwRgBWHbIA6atl/czRcDnXV9p7TCtcE8YsrgFYyT07D7/AmjPl1taiJmYnrojmqrQbOY/WE7nvHftjRkJoQcywYOfLY4zy4VOwhD6//Kpzo6klsLTuZgWMP1Wr4BzNB41EyjN68lzRiPhTQN0E8MuXwNSUS2sOODr96r6m9Z15Gg0iuzs60pz3HNXXoreRDjb5qZODprnEau0i94A9vuGaDS+Lr0QFV95ZAnCQ0t0j11QgxnuiBL0UIBNLYexCyTn3T5+cPDPMBC9bsMkCLzWvrapIFcGqrboxzx9g6KUh9jH24Eeckwndqqz5S+I0GeZbEZEAjHqgNSCPMDX0L8+CBvm6atT5kXpy1gls5YDsEDds0bTl9baf";
|
String originWord = decrypt(encryptWord, getPrivateKey());
|
System.out.println("解密后的字符串:"+originWord);*/
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
}
|
}
|