支持rsa加解密

This commit is contained in:
ztzh_xieyun 2024-05-11 16:40:25 +08:00
parent 7704dd58ad
commit 2b932faeac
12 changed files with 583 additions and 325 deletions

View File

@ -380,8 +380,8 @@ public class AppConfigHandler {
Config hazelcastConfig = new Config();
hazelcastConfig.setClusterName(sacVertxConfig.getClusterName()); // 集群名字
NetworkConfig networkConfig = new NetworkConfig();
networkConfig.setPort(5701);
networkConfig.setPortAutoIncrement(true);
networkConfig.setPort(sacVertxConfig.getNetworkPort());
networkConfig.setPortAutoIncrement(sacVertxConfig.isPortAutoIncrement());
JoinConfig join = new JoinConfig();
TcpIpConfig tcpIpConfig = new TcpIpConfig();
@ -394,15 +394,15 @@ public class AppConfigHandler {
hazelcastConfig.setNetworkConfig(networkConfig);
// TODO 还有问题,不会使用
ManagementCenterConfig managementCenterConfig = new ManagementCenterConfig();
Set<String> interfaces = new HashSet<>();
interfaces.add("http://192.168.1.68:8080/mancenter");
managementCenterConfig.setTrustedInterfaces(interfaces);
hazelcastConfig.setManagementCenterConfig(managementCenterConfig);
// ManagementCenterConfig managementCenterConfig = new ManagementCenterConfig();
// Set<String> interfaces = new HashSet<>();
// interfaces.add("http://192.168.1.68:8080/mancenter");
// managementCenterConfig.setTrustedInterfaces(interfaces);
// hazelcastConfig.setManagementCenterConfig(managementCenterConfig);
return hazelcastConfig;
}
public static Vertx createHazelcastClusterVertx() {
public static void createHazelcastClusterVertx() {
Config hazelcastConfig = hazelcastConfig(sacVertxConfig);
ClusterManager hazelcastClusterManager = new HazelcastClusterManager(hazelcastConfig);
// TODO 编解码线程池,后面优化协程等方式
@ -437,7 +437,6 @@ public class AppConfigHandler {
log.info("hazelcastClusterManager create failure");
}
});
return VERTX;
}
/***
@ -452,7 +451,6 @@ public class AppConfigHandler {
private static void createVertxRouter() {
// consul初始化
// ConsulHandler.init(vertx);
// ConsulHandler.init1(vertx);
// 从redis同步app配置
initAllAppConfig();

View File

@ -0,0 +1,39 @@
package com.sf.vertx.handle;
import io.netty.handler.codec.http.HttpResponseStatus;
public class MockException extends RuntimeException {
private static final long serialVersionUID = 7975954645547803571L;
private final int statusCode;
private final String payload;
public MockException() {
this(500, null, null);
}
public MockException(int statusCode) {
this(statusCode, null, null);
}
public MockException(int statusCode, Throwable cause) {
this(statusCode, null, cause);
}
public MockException(int statusCode, String payload) {
this(statusCode, payload, null);
}
public MockException(int statusCode, String payload, Throwable cause) {
super(HttpResponseStatus.valueOf(statusCode).reasonPhrase(), cause, false, false);
this.statusCode = statusCode;
this.payload = payload;
}
public int getStatusCode() {
return statusCode;
}
public String getPayload() {
return payload;
}
}

View File

@ -39,7 +39,7 @@ public class ParameterCheckHandlerImpl implements ParameterCheckHandler {
// mock
String mockResponse = AppConfigHandler.mock(key);
if(StringUtils.isNotBlank(mockResponse)) {
rc.fail(new HttpException(10020, mockResponse));
rc.fail(new MockException(10020, mockResponse));
return;
}
} catch (Exception e) {

View File

@ -15,6 +15,7 @@ public class RestfulFailureHandlerImpl implements RestfulFailureHandler {
@Override
public void handle(RoutingContext frc) {
int statusCode = 500;
JsonObject errorJson = null;
try {
Throwable failure = frc.failure();
@ -25,15 +26,24 @@ public class RestfulFailureHandlerImpl implements RestfulFailureHandler {
} else {
errorJson = SacErrorCode.returnErrorMsg(httpException.getStatusCode());
}
} else if (failure instanceof MockException) {
MockException httpException = (MockException) failure;
if (StringUtils.isNoneBlank(httpException.getPayload())) {
statusCode = 200;
errorJson = new JsonObject(httpException.getPayload());
} else {
errorJson = SacErrorCode.returnErrorMsg(httpException.getStatusCode());
}
} else {
errorJson = SacErrorCode.returnErrorMsg(SacErrorCode.DEFAULT_ERROR_CODE);
}
} catch (Exception e) {
e.printStackTrace();
errorJson = SacErrorCode.returnErrorMsg(SacErrorCode.DEFAULT_ERROR_CODE);
}
frc.response().setChunked(true).setStatusCode(500).putHeader("Content-Type", "application/json")
frc.response().setChunked(true).setStatusCode(statusCode).putHeader("Content-Type", "application/json")
.putHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(errorJson.size())).end(errorJson.toBuffer());
return;
}

View File

@ -50,10 +50,13 @@ public class DynamicBuildServer implements ApplicationRunner {
* @throws Exception
*/
private void startVertxService() throws Exception {
// 单机
//AppConfigHandler.createVertx();
// 集群
AppConfigHandler.createHazelcastClusterVertx();
if(sacVertxConfig.getDeploymentMode() == 2) {
// 集群
AppConfigHandler.createHazelcastClusterVertx();
} else {
// 单机
AppConfigHandler.createVertx();
}
}
}

View File

@ -13,18 +13,27 @@ import lombok.Data;
@Component
@Data
public class SacVertxConfig {
@Value("${server.vertx.server.default.port}")
@Value("${server.vertx.server.default.port:80}")
private Integer port;
@Value("${server.vertx.cluster.ip}")
@Value("${server.vertx.cluster.ip:127.0.0.1}")
private String clusterIp;
@Value("${server.vertx.requestModel}")
@Value("${server.vertx.cluster.networkPort:5701}")
private Integer networkPort;
@Value("${server.vertx.cluster.portAutoIncrement:false}")
private boolean portAutoIncrement;
@Value("${server.vertx.requestModel:2}")
private Integer requestModel;
@Value("${server.vertx.rpcUri}")
@Value("${server.vertx.rpcUri:/rpc}")
private String rpcUri;
@Value("${server.vertx.deploymentMode:1}")
private Integer deploymentMode;
@Value("${server.vertx.cluster.clusterName}")
@Value("${server.vertx.cluster.clusterName:sac}")
private String clusterName;
}

View File

@ -15,25 +15,25 @@ public class MainSecurity {
* @param pubKey
* @return
*/
// public static String rsaEncrypt(String content, String pubKey) {
// try {
// return RSA2Utils.encrypt(content, pubKey);
// } catch (Exception e) {
// LOGGER.info("RSA加密失败");
// e.printStackTrace();
// return null;
// }
// }
public static String rsaEncrypt(String content, String pubKey) {
try {
return RSAUtil.encrypt1(content, pubKey);
} catch (Exception e) {
LOGGER.info("RSA加密失败");
e.printStackTrace();
return null;
}
}
// public static String rsaDecrypt(String content, String priKey) {
// try {
// return RSA2Utils.decrypt(content, priKey);
// } catch (Exception e) {
// LOGGER.info("RSA解密失败");
// e.printStackTrace();
// return null;
// }
// }
public static String rsaDecrypt(String content, String priKey) {
try {
return RSAUtil.decrypt1(content, priKey);
} catch (Exception e) {
LOGGER.info("RSA解密失败");
e.printStackTrace();
return null;
}
}
public static String aesEncrypt(String content, String key) {
try {
@ -66,13 +66,13 @@ public class MainSecurity {
}
public static void main(String[] args) {
System.out.println(aesEncrypt("{\n"
+ " \"errorCode\": \"中文\",\n"
+ " \"result\": 0,\n"
+ " \"data\": {\n"
+ " \"username\" : \"测试\"\n"
+ " }\n"
+ "}", "dadddsdfadfadsfa33323223"));
System.out.println(aesDecrypt("59A69B6BBCF046C3CF9953C5CC078CC638602D454BBCE8CF8F0DA6AF1F3A4707686263C834A612C5C6F22D9F897B13B434A53E32AAD4036E12A5098565AB1AD352B400FC23354ECE977DDC670F793992D7F884264A9689B000E37157B4D41351", "dadddsdfadfadsfa33323223"));
// System.out.println(aesEncrypt("{\n"
// + " \"errorCode\": \"中文\",\n"
// + " \"result\": 0,\n"
// + " \"data\": {\n"
// + " \"username\" : \"测试\"\n"
// + " }\n"
// + "}", "dadddsdfadfadsfa33323223"));
// System.out.println(aesDecrypt("59A69B6BBCF046C3CF9953C5CC078CC638602D454BBCE8CF8F0DA6AF1F3A4707686263C834A612C5C6F22D9F897B13B434A53E32AAD4036E12A5098565AB1AD352B400FC23354ECE977DDC670F793992D7F884264A9689B000E37157B4D41351", "dadddsdfadfadsfa33323223"));
}
}

View File

@ -1,276 +1,276 @@
//package com.sf.vertx.security;
//
//
//import javax.crypto.BadPaddingException;
//import javax.crypto.Cipher;
//import javax.crypto.IllegalBlockSizeException;
//import javax.crypto.NoSuchPaddingException;
//import java.io.ByteArrayOutputStream;
//import java.io.IOException;
//import java.io.UnsupportedEncodingException;
//import java.security.*;
//import java.security.spec.InvalidKeySpecException;
//import java.security.spec.PKCS8EncodedKeySpec;
//import java.security.spec.X509EncodedKeySpec;
//import java.util.List;
//
///**
// * 本类进行非对称加密不推荐使用非对称加密对长字符串进行加密或者解密徒增资源消耗另外由于长度限制过长的字符串的加密和解密会使用循环对数据分段加密本类采用的
// * 密钥字符串均为Base64加密后的
// * 另外所有异常都会抛出
// * 下面将会列举几个可以自定义或者暴露出去的接口和参数
// * {@link #IS_LONG_TEXT} 是否否对长文本处理
// * {@link #RESULT_TYPE} 密文结果1=base64 2=hex
// * {@link #RSA_ALGORITHM} RSA算法
// * {@link #encrypt(String, String)} 加密方法
// * {@link #decrypt(String, String)} 解密方法
// * {@link #getKeyPair} 解密方法
// */
//public class RSA2Utils {
// /**
// * 是否对长文本加密请参照{@link #MAX_DECRYPT_BLOCK}{@link #MAX_ENCRYPT_BLOCK}
// */
// private static final boolean IS_LONG_TEXT = true;
// /**
// * 结果类型
// */
// private static final int RESULT_TYPE = 2;
// /**
// * RSA 算法
// */
// private static final String RSA_ALGORITHM = "RSA";
// /**
// * 长文本解密块大小
// */
// private static final int MAX_DECRYPT_BLOCK = 128;
// /**
// * 长文本加密块大小
// */
// private static final int MAX_ENCRYPT_BLOCK = 117;
// /**
// * KyeSize
// */
// private static final int KEY_SIZE = 2048;
//
// /**
// * 加密
// *
// * @param content 待加密的字符串
// * @param pubKey 公钥字符串
// * @return 加密后的文本
// * @throws Exception 异常
// */
// public static String encrypt(String content, String pubKey) throws Exception {
// byte[] data = StringUtils.getBytes(content);
// PublicKey publicKey = string2PubKey(pubKey);
// byte[] resultArr;
// if (IS_LONG_TEXT) {
// resultArr = encryptLongStr(data, publicKey);
// } else {
// resultArr = encrypt(data, publicKey);
// }
// String result;
// switch (RESULT_TYPE) {
// case 1:
// result = Base64Utils.encode(resultArr);
// break;
// case 2:
// result = HexUtils.bytes2Hex(resultArr);
// break;
// default:
// throw new Exception("Unsupport result type");
// }
// return result;
// }
//
// /**
// * @param content 密文内容
// * @param priKey 私钥
// * @return 解密后的字符串
// * @throws Exception 异常
// */
// public static String decrypt(String content, String priKey) throws Exception {
// byte[] data;
// switch (RESULT_TYPE) {
// case 1:
// data = Base64Utils.decode(content);
// break;
// case 2:
// data = HexUtils.hex2Bytes(content);
// break;
// default:
// throw new Exception("Unsupport result type");
// }
// PrivateKey privateKey = string2PrivateKey(priKey);
// byte[] result;
// if (IS_LONG_TEXT) {
// result = decryptLongStr(data, privateKey);
// } else {
// result = decrypt(privateKey, data);
// }
// return StringUtils.bytes2String(result);
// }
//
// /**
// * 响应公私钥对
// *
// * @return 0号 公钥 1号 私钥
// * @throws NoSuchAlgorithmException 异常
// */
// public static List<String> getKeyPair() throws NoSuchAlgorithmException {
// KeyPair keyPairObj = getKeyPairObj();
// return List.of(Base64Utils.encode(keyPairObj.getPublic().getEncoded()), Base64Utils.encode(keyPairObj.getPrivate().getEncoded()));
// }
//
// /**
// * 将公钥字符串转化为对象
// *
// * @param s base64字符串
// * @return 公钥
// * @throws NoSuchAlgorithmException 异常
// * @throws UnsupportedEncodingException 异常
// * @throws InvalidKeySpecException 异常
// */
// private static PublicKey string2PubKey(String s) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException {
// KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
// X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64Utils.decode(s));
// return keyFactory.generatePublic(keySpec);
// }
//
// /**
// * 对段字符串进行加密
// *
// * @param bytes 字节数组
// * @param publicKey 公钥
// * @return 加密后的数组
// * @throws InvalidKeyException 异常
// * @throws BadPaddingException 异常
// * @throws IllegalBlockSizeException 异常
// * @throws NoSuchPaddingException 异常
// * @throws NoSuchAlgorithmException 异常
// */
// private static byte[] encrypt(byte[] bytes, PublicKey publicKey) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException {
// Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
// cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// return cipher.doFinal(bytes);
// }
//
// /**
// * 对长字符串进行加密
// *
// * @param bytes 字节数组
// * @param publicKey 公钥
// * @return 加密后的数组
// * @throws NoSuchPaddingException 异常
// * @throws NoSuchAlgorithmException 异常
// * @throws InvalidKeyException 异常
// */
// private static byte[] encryptLongStr(byte[] bytes, PublicKey publicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
// Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
// cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// int inputLen = bytes.length;
// byte[] encryptedData = new byte[0];
// try (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(bytes, offSet, MAX_ENCRYPT_BLOCK);
// } else {
// cache = cipher.doFinal(bytes, offSet, inputLen - offSet);
// }
// out.write(cache, 0, cache.length);
// i++;
// offSet = i * MAX_ENCRYPT_BLOCK;
// }
// encryptedData = out.toByteArray();
// } catch (IOException | BadPaddingException | IllegalBlockSizeException e) {
// e.printStackTrace();
// }
// return encryptedData;
// }
//
// /**
// * 私钥字符串转为私钥对象
// *
// * @param priStr 私钥字符串
// * @return 私钥对象
// * @throws NoSuchAlgorithmException 异常
// * @throws InvalidKeySpecException 异常
// */
// private static PrivateKey string2PrivateKey(String priStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
// PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64Utils.decode(priStr));
// KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
// return keyFactory.generatePrivate(keySpec);
// }
//
// /**
// * 解密
// *
// * @param privateKey 私钥
// * @param bytes 字节数组
// * @return 解密后的字节数组
// * @throws NoSuchPaddingException 异常
// * @throws NoSuchAlgorithmException 异常
// * @throws BadPaddingException 异常
// * @throws IllegalBlockSizeException 异常
// * @throws InvalidKeyException 异常
// */
// public static byte[] decrypt(PrivateKey privateKey, byte[] bytes) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
// Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
// cipher.init(Cipher.DECRYPT_MODE, privateKey);
// return cipher.doFinal(bytes);
// }
//
// /**
// * 解密
// *
// * @param data 解密前的字节数组
// * @param privateKey 私钥
// * @return 解密后的字节数组
// * @throws InvalidKeyException 异常
// * @throws NoSuchPaddingException 异常
// * @throws NoSuchAlgorithmException 异常
// */
// public static byte[] decryptLongStr(byte[] data, PrivateKey privateKey) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException {
// Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
// cipher.init(Cipher.DECRYPT_MODE, privateKey);
// int inputLen = data.length;
// byte[] result = new byte[0];
// try (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(data, offSet, MAX_DECRYPT_BLOCK);
// } else {
// cache = cipher.doFinal(data, offSet, inputLen - offSet);
// }
// out.write(cache, 0, cache.length);
// i++;
// offSet = i * MAX_DECRYPT_BLOCK;
// }
// result = out.toByteArray();
// } catch (BadPaddingException | IllegalBlockSizeException | IOException e) {
// e.printStackTrace();
// }
// return result;
// }
//
// /**
// * 获得一堆公私钥
// *
// * @return KeyPair对象
// * @throws NoSuchAlgorithmException 异常
// */
// private static KeyPair getKeyPairObj() throws NoSuchAlgorithmException {
// KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM);
// SecureRandom secureRandom = new SecureRandom(StringUtils.getBytes(String.valueOf(System.currentTimeMillis())));
// keyPairGenerator.initialize(KEY_SIZE, secureRandom);
// return keyPairGenerator.genKeyPair();
// }
//}
package com.sf.vertx.security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.List;
/**
* 本类进行非对称加密不推荐使用非对称加密对长字符串进行加密或者解密徒增资源消耗另外由于长度限制过长的字符串的加密和解密会使用循环对数据分段加密本类采用的
* 密钥字符串均为Base64加密后的
* 另外所有异常都会抛出
* 下面将会列举几个可以自定义或者暴露出去的接口和参数
* {@link #IS_LONG_TEXT} 是否否对长文本处理
* {@link #RESULT_TYPE} 密文结果1=base64 2=hex
* {@link #RSA_ALGORITHM} RSA算法
* {@link #encrypt(String, String)} 加密方法
* {@link #decrypt(String, String)} 解密方法
* {@link #getKeyPair} 解密方法
*/
public class RSA2Utils {
/**
* 是否对长文本加密请参照{@link #MAX_DECRYPT_BLOCK}{@link #MAX_ENCRYPT_BLOCK}
*/
private static final boolean IS_LONG_TEXT = true;
/**
* 结果类型
*/
private static final int RESULT_TYPE = 2;
/**
* RSA 算法
*/
private static final String RSA_ALGORITHM = "RSA";
/**
* 长文本解密块大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* 长文本加密块大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* KyeSize
*/
private static final int KEY_SIZE = 2048;
/**
* 加密
*
* @param content 待加密的字符串
* @param pubKey 公钥字符串
* @return 加密后的文本
* @throws Exception 异常
*/
public static String encrypt(String content, String pubKey) throws Exception {
byte[] data = StringUtils.getBytes(content);
PublicKey publicKey = string2PubKey(pubKey);
byte[] resultArr;
if (IS_LONG_TEXT) {
resultArr = encryptLongStr(data, publicKey);
} else {
resultArr = encrypt(data, publicKey);
}
String result;
switch (RESULT_TYPE) {
case 1:
result = Base64Utils.encode(resultArr);
break;
case 2:
result = HexUtils.bytes2Hex(resultArr);
break;
default:
throw new Exception("Unsupport result type");
}
return result;
}
/**
* @param content 密文内容
* @param priKey 私钥
* @return 解密后的字符串
* @throws Exception 异常
*/
public static String decrypt(String content, String priKey) throws Exception {
byte[] data;
switch (RESULT_TYPE) {
case 1:
data = Base64Utils.decode(content);
break;
case 2:
data = HexUtils.hex2Bytes(content);
break;
default:
throw new Exception("Unsupport result type");
}
PrivateKey privateKey = string2PrivateKey(priKey);
byte[] result;
if (IS_LONG_TEXT) {
result = decryptLongStr(data, privateKey);
} else {
result = decrypt(privateKey, data);
}
return StringUtils.bytes2String(result);
}
/**
* 响应公私钥对
*
* @return 0号 公钥 1号 私钥
* @throws NoSuchAlgorithmException 异常
*/
public static List<String> getKeyPair() throws NoSuchAlgorithmException {
KeyPair keyPairObj = getKeyPairObj();
return List.of(Base64Utils.encode(keyPairObj.getPublic().getEncoded()), Base64Utils.encode(keyPairObj.getPrivate().getEncoded()));
}
/**
* 将公钥字符串转化为对象
*
* @param s base64字符串
* @return 公钥
* @throws NoSuchAlgorithmException 异常
* @throws UnsupportedEncodingException 异常
* @throws InvalidKeySpecException 异常
*/
private static PublicKey string2PubKey(String s) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException {
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64Utils.decode(s));
return keyFactory.generatePublic(keySpec);
}
/**
* 对段字符串进行加密
*
* @param bytes 字节数组
* @param publicKey 公钥
* @return 加密后的数组
* @throws InvalidKeyException 异常
* @throws BadPaddingException 异常
* @throws IllegalBlockSizeException 异常
* @throws NoSuchPaddingException 异常
* @throws NoSuchAlgorithmException 异常
*/
private static byte[] encrypt(byte[] bytes, PublicKey publicKey) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(bytes);
}
/**
* 对长字符串进行加密
*
* @param bytes 字节数组
* @param publicKey 公钥
* @return 加密后的数组
* @throws NoSuchPaddingException 异常
* @throws NoSuchAlgorithmException 异常
* @throws InvalidKeyException 异常
*/
private static byte[] encryptLongStr(byte[] bytes, PublicKey publicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int inputLen = bytes.length;
byte[] encryptedData = new byte[0];
try (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(bytes, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(bytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
encryptedData = out.toByteArray();
} catch (IOException | BadPaddingException | IllegalBlockSizeException e) {
e.printStackTrace();
}
return encryptedData;
}
/**
* 私钥字符串转为私钥对象
*
* @param priStr 私钥字符串
* @return 私钥对象
* @throws NoSuchAlgorithmException 异常
* @throws InvalidKeySpecException 异常
*/
private static PrivateKey string2PrivateKey(String priStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64Utils.decode(priStr));
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
return keyFactory.generatePrivate(keySpec);
}
/**
* 解密
*
* @param privateKey 私钥
* @param bytes 字节数组
* @return 解密后的字节数组
* @throws NoSuchPaddingException 异常
* @throws NoSuchAlgorithmException 异常
* @throws BadPaddingException 异常
* @throws IllegalBlockSizeException 异常
* @throws InvalidKeyException 异常
*/
public static byte[] decrypt(PrivateKey privateKey, byte[] bytes) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(bytes);
}
/**
* 解密
*
* @param data 解密前的字节数组
* @param privateKey 私钥
* @return 解密后的字节数组
* @throws InvalidKeyException 异常
* @throws NoSuchPaddingException 异常
* @throws NoSuchAlgorithmException 异常
*/
public static byte[] decryptLongStr(byte[] data, PrivateKey privateKey) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException {
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
int inputLen = data.length;
byte[] result = new byte[0];
try (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(data, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
result = out.toByteArray();
} catch (BadPaddingException | IllegalBlockSizeException | IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 获得一堆公私钥
*
* @return KeyPair对象
* @throws NoSuchAlgorithmException 异常
*/
private static KeyPair getKeyPairObj() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM);
SecureRandom secureRandom = new SecureRandom(StringUtils.getBytes(String.valueOf(System.currentTimeMillis())));
keyPairGenerator.initialize(KEY_SIZE, secureRandom);
return keyPairGenerator.genKeyPair();
}
}

View File

@ -0,0 +1,173 @@
package com.sf.vertx.security;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class RSAUtil {
public static final String KEY_ALGORITHM = "RSA";
private static final String PUBLIC_KEY = "RSAPublicKey";
private static final String PRIVATE_KEY = "RSAPrivateKey";
// 1024 bits RSA 密钥对最大加密明文大小
private static final int MAX_ENCRYPT_BLOCK = 117;
// 1024 bits RSA 密钥对最大解密密文大小
private static final int MAX_DECRYPT_BLOCK = 128;
// 生成密钥对
public static Map<String, Object> initKey(int keysize) throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
// 设置密钥对的 bit 越大越安全
keyPairGen.initialize(keysize);
KeyPair keyPair = keyPairGen.generateKeyPair();
// 获取公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 获取私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
// 获取公钥字符串
public static String getPublicKeyStr(Map<String, Object> keyMap) {
// 获得 map 中的公钥对象转为 key 对象
Key key = (Key) keyMap.get(PUBLIC_KEY);
// 编码返回字符串
return encryptBASE64(key.getEncoded());
}
// 获取私钥字符串
public static String getPrivateKeyStr(Map<String, Object> keyMap) {
// 获得 map 中的私钥对象转为 key 对象
Key key = (Key) keyMap.get(PRIVATE_KEY);
// 编码返回字符串
return encryptBASE64(key.getEncoded());
}
// 获取公钥
public static PublicKey getPublicKey(String publicKeyString) throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] publicKeyByte = Base64.getDecoder().decode(publicKeyString);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyByte);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
return keyFactory.generatePublic(keySpec);
}
// 获取私钥
public static PrivateKey getPrivateKey(String privateKeyString) throws Exception {
byte[] privateKeyByte = Base64.getDecoder().decode(privateKeyString);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyByte);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
return keyFactory.generatePrivate(keySpec);
}
/**
* BASE64 编码返回加密字符串
*
* @param key 需要编码的字节数组
* @return 编码后的字符串
*/
public static String encryptBASE64(byte[] key) {
return new String(Base64.getEncoder().encode(key));
}
/**
* BASE64 解码返回字节数组
*
* @param key 待解码的字符串
* @return 解码后的字节数组
*/
public static byte[] decryptBASE64(String key) {
return Base64.getDecoder().decode(key);
}
/**
* 公钥加密
*
* @param text 待加密的明文字符串
* @param publicKeyStr 公钥
* @return 加密后的密文
*/
public static String encrypt1(String text, String publicKeyStr) {
try {
log.info("明文字符串为:[{}]", text);
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKeyStr));
byte[] tempBytes = cipher.doFinal(text.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(tempBytes);
} catch (Exception e) {
throw new RuntimeException("加密字符串[" + text + "]时遇到异常", e);
}
}
/**
* 私钥解密
*
* @param secretText 待解密的密文字符串
* @param privateKeyStr 私钥
* @return 解密后的明文
*/
public static String decrypt1(String secretText, String privateKeyStr) {
try {
// 生成私钥
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKeyStr));
// 密文解码
byte[] secretTextDecoded = Base64.getDecoder().decode(secretText.getBytes("UTF-8"));
byte[] tempBytes = cipher.doFinal(secretTextDecoded);
return new String(tempBytes);
} catch (Exception e) {
throw new RuntimeException("解密字符串[" + secretText + "]时遇到异常", e);
}
}
public static void main(String[] args) throws Exception {
Map<String, Object> keyMap;
String cipherText;
// 原始明文
String content = "{\"data\":{\"a\":1,\"b\":\"dd\"},\"divideHttpUrl\":{\"company\":{\"aesKey\":\"dadddsdfadfadsfa33323223\"}}}\n"
+ "";
// 生成密钥对
keyMap = initKey(1024);
String publicKey = getPublicKeyStr(keyMap);
log.info("公钥:[{}],长度:[{}]", publicKey, publicKey.length());
String privateKey = getPrivateKeyStr(keyMap);
log.info("私钥:[{}],长度:[{}]", privateKey, privateKey.length());
publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuIBxYMYWgIau1BKjTpM/9JhIHRnO4QoaiOrVJk+OFWAJFpFrZoDj3JYQF4ywD8uWOx28EBf+g+U8UIE0pS93IEvm/O47VOwSqSvc5tpXmrxHTVgHSqcXqXkm4+q64c525N5bhUbReXI/CSKU62EH7MWapjHD7vPKGVCwjg8RHCQIDAQAB";
privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAK4gHFgxhaAhq7UEqNOkz/0mEgdGc7hChqI6tUmT44VYAkWkWtmgOPclhAXjLAPy5Y7HbwQF/6D5TxQgTSlL3cgS+b87jtU7BKpK9zm2leavEdNWAdKpxepeSbj6rrhznbk3luFRtF5cj8JIpTrYQfsxZqmMcPu88oZULCODxEcJAgMBAAECgYAA+yU4/xgPny6Sm97ChoD80k6pzpubAP6URKJMXSQcFBaxtPnZivfU005qNY7qGApXBj69Otw8pC8YvsP+KEsHAmPS78AmzAlh6rojkwl+A1F3a23CyxWKDik/HWsXJ1WSl5ljw/+rW6/38YVfPEKZSOWOTwfYxFWI553j05CVKQJBALkhR60uwGaGpV1ApHwcuaSN6rVQ46D67qmkKG3rLkZJyDziFBabl685UCKiDXqwRoX3UWI0FDqDUhSqoBo/LJUCQQDwyGJiUIAI8bTj6q4+1LxeHMlcJWXaRvOK0BocH+6KpybMKf0R478ziYTtNiaSY45syaDQKofVyE8kzTN37J+lAkAs9EHdcd7ShpudG1dVs/v4U2XNBYlgy84sb2pJ1rPz6XKwJg3Ot5WLvRUSc9tmEWvul/GxMQhAdSb3Ub9y4ChJAkEA7Wj3MO8kvyzr6gpcklEaBkWl+TharBVnTwiPpgmKH6ZeZ9JC2B/SR9OhgG7zK0YEiZlo+bflxVHDT4sQ438pjQJBALIQpdg34BQwWMTx4MxP0Wji51JDZM7h24SReb0RktfsY9s6ZU6mbu3oJNnInD+GQkRJkYNkK4DPrczIxnMpddE=";
// 加密
cipherText = encrypt1(content, publicKey);
log.info("加密后的密文:[{}],长度:[{}]", cipherText, cipherText.length());
// 解密
cipherText = "DaztB3mXoFSZ6wtu4K1mpnFryyeBckeIa0RoLpejCltFj9UZWP3FwTw50SeFlK5dqWE/J0jQUBSRZDJ8qZ2/vnuNqaUxn+JcaUTqlShYV8wbYoqr8tCSFJ0PoHLMdkjS1xFcADqsgRTSsB67dd4qth3K5vU1iQQR30QHPv3I6nY=";
String plainText = decrypt1(cipherText, privateKey);
log.info("解密后明文:[{}]", plainText);
}
}

View File

@ -367,7 +367,7 @@ public class ReverseProxy implements HttpProxy {
log.info("responseData:{}", responseData);
// 加密
String dataStr = bodyEncrypt(responseData.toString(), appCode);
log.info("aesEncrypt dataStr:{}", dataStr);
log.info("encrypt dataStr:{}", dataStr);
Buffer buffer = Buffer.buffer(dataStr);
ProxyResponse proxyResponse = proxyRequest.response().setStatusCode(200)
.putHeader("content-type", "application/json").setBody(Body.body(buffer));
@ -457,6 +457,8 @@ public class ReverseProxy implements HttpProxy {
switch (dataSecurity.getAlgorithm()) {
case "AES":
return MainSecurity.aesEncrypt(body, dataSecurity.getPrivateKey());
case "RSA":
return MainSecurity.rsaEncrypt(body, dataSecurity.getPublicKey());
default:
break;
}
@ -469,6 +471,8 @@ public class ReverseProxy implements HttpProxy {
switch (dataSecurity.getAlgorithm()) {
case "AES":
return MainSecurity.aesDecrypt(body, dataSecurity.getPrivateKey());
case "RSA":
return MainSecurity.rsaDecrypt(body, dataSecurity.getPrivateKey());
default:
break;
}

View File

@ -1,6 +1,7 @@
# 开发环境配置
server:
vertx:
deploymentMode: 1 # 1:单机 2:集群
requestModel: 2 # 1: 客户端传递uri. 2: uri vertx代理,不对客户端暴露uri
rpcUri: /rpc
environment: dev
@ -10,6 +11,8 @@ server:
cluster:
ip: 192.168.1.68
clusterName: sac-dev
networkPort: 5701
portAutoIncrement: false
# 服务器的HTTP端口默认为8080
port: 5566
servlet:

View File

@ -0,0 +1,19 @@
package com.sf.vertx;
import org.junit.Test;
import com.sf.vertx.security.MainSecurity;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TestMainSecurity {
@Test
public void rsaEncryptTest() {
String content = "sddfadfa";
String pubKey = "sdafsd";
String data = MainSecurity.rsaEncrypt(content, pubKey);
log.info("data:{}", data);
}
}