diff --git a/sf-vertx/src/main/java/com/sf/vertx/handle/AppConfigHandler.java b/sf-vertx/src/main/java/com/sf/vertx/handle/AppConfigHandler.java index 1c8ead6..cd9f80b 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/handle/AppConfigHandler.java +++ b/sf-vertx/src/main/java/com/sf/vertx/handle/AppConfigHandler.java @@ -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 interfaces = new HashSet<>(); - interfaces.add("http://192.168.1.68:8080/mancenter"); - managementCenterConfig.setTrustedInterfaces(interfaces); - hazelcastConfig.setManagementCenterConfig(managementCenterConfig); +// ManagementCenterConfig managementCenterConfig = new ManagementCenterConfig(); +// Set 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(); diff --git a/sf-vertx/src/main/java/com/sf/vertx/handle/MockException.java b/sf-vertx/src/main/java/com/sf/vertx/handle/MockException.java new file mode 100644 index 0000000..c2cfded --- /dev/null +++ b/sf-vertx/src/main/java/com/sf/vertx/handle/MockException.java @@ -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; + } +} \ No newline at end of file diff --git a/sf-vertx/src/main/java/com/sf/vertx/handle/ParameterCheckHandlerImpl.java b/sf-vertx/src/main/java/com/sf/vertx/handle/ParameterCheckHandlerImpl.java index 69ba647..e47a24d 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/handle/ParameterCheckHandlerImpl.java +++ b/sf-vertx/src/main/java/com/sf/vertx/handle/ParameterCheckHandlerImpl.java @@ -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) { diff --git a/sf-vertx/src/main/java/com/sf/vertx/handle/RestfulFailureHandlerImpl.java b/sf-vertx/src/main/java/com/sf/vertx/handle/RestfulFailureHandlerImpl.java index 9938310..0deebe7 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/handle/RestfulFailureHandlerImpl.java +++ b/sf-vertx/src/main/java/com/sf/vertx/handle/RestfulFailureHandlerImpl.java @@ -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; } diff --git a/sf-vertx/src/main/java/com/sf/vertx/init/DynamicBuildServer.java b/sf-vertx/src/main/java/com/sf/vertx/init/DynamicBuildServer.java index 1955375..8e7075f 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/init/DynamicBuildServer.java +++ b/sf-vertx/src/main/java/com/sf/vertx/init/DynamicBuildServer.java @@ -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(); + } } } diff --git a/sf-vertx/src/main/java/com/sf/vertx/init/SacVertxConfig.java b/sf-vertx/src/main/java/com/sf/vertx/init/SacVertxConfig.java index e875d00..196a316 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/init/SacVertxConfig.java +++ b/sf-vertx/src/main/java/com/sf/vertx/init/SacVertxConfig.java @@ -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; } diff --git a/sf-vertx/src/main/java/com/sf/vertx/security/MainSecurity.java b/sf-vertx/src/main/java/com/sf/vertx/security/MainSecurity.java index c4ee9fd..affb33c 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/security/MainSecurity.java +++ b/sf-vertx/src/main/java/com/sf/vertx/security/MainSecurity.java @@ -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")); } } diff --git a/sf-vertx/src/main/java/com/sf/vertx/security/RSA2Utils.java b/sf-vertx/src/main/java/com/sf/vertx/security/RSA2Utils.java index 72b109c..1dc9ca0 100644 --- a/sf-vertx/src/main/java/com/sf/vertx/security/RSA2Utils.java +++ b/sf-vertx/src/main/java/com/sf/vertx/security/RSA2Utils.java @@ -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 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 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(); + } +} diff --git a/sf-vertx/src/main/java/com/sf/vertx/security/RSAUtil.java b/sf-vertx/src/main/java/com/sf/vertx/security/RSAUtil.java new file mode 100644 index 0000000..85a3f49 --- /dev/null +++ b/sf-vertx/src/main/java/com/sf/vertx/security/RSAUtil.java @@ -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 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 keyMap = new HashMap<>(2); + keyMap.put(PUBLIC_KEY, publicKey); + keyMap.put(PRIVATE_KEY, privateKey); + return keyMap; + } + + // 获取公钥字符串 + public static String getPublicKeyStr(Map keyMap) { + // 获得 map 中的公钥对象,转为 key 对象 + Key key = (Key) keyMap.get(PUBLIC_KEY); + // 编码返回字符串 + return encryptBASE64(key.getEncoded()); + } + + // 获取私钥字符串 + public static String getPrivateKeyStr(Map 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 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); + } +} + diff --git a/sf-vertx/src/main/java/io/vertx/httpproxy/impl/ReverseProxy.java b/sf-vertx/src/main/java/io/vertx/httpproxy/impl/ReverseProxy.java index a822b09..ca54f79 100644 --- a/sf-vertx/src/main/java/io/vertx/httpproxy/impl/ReverseProxy.java +++ b/sf-vertx/src/main/java/io/vertx/httpproxy/impl/ReverseProxy.java @@ -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; } diff --git a/sf-vertx/src/main/resources/application.yml b/sf-vertx/src/main/resources/application.yml index aa11647..4a5420c 100644 --- a/sf-vertx/src/main/resources/application.yml +++ b/sf-vertx/src/main/resources/application.yml @@ -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: diff --git a/sf-vertx/src/test/java/com/sf/vertx/TestMainSecurity.java b/sf-vertx/src/test/java/com/sf/vertx/TestMainSecurity.java new file mode 100644 index 0000000..8ecd8b7 --- /dev/null +++ b/sf-vertx/src/test/java/com/sf/vertx/TestMainSecurity.java @@ -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); + } +}