diff --git a/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/handler/ProxyMessageAuthHandler.java b/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/handler/ProxyMessageAuthHandler.java index 672576aa..233d23d3 100644 --- a/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/handler/ProxyMessageAuthHandler.java +++ b/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/handler/ProxyMessageAuthHandler.java @@ -45,6 +45,10 @@ public class ProxyMessageAuthHandler implements ProxyMessageHandler { context.channel().close(); } + // 默认设置为非安全链路,需要服务端确认后,再设置为安全链路 + Attribute booleanAttribute = context.attr(Constants.IS_SECURITY); + booleanAttribute.set(false); + // 获取认证成功的后的公钥信息,并生成随机密码,加密发到服务端确认 String publicKey = load.get("publicKey").getString(); byte[] secureKey = SmEncryptUtil.generateSm4Key(); diff --git a/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/handler/ProxyMessageSecureKeyHandler.java b/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/handler/ProxyMessageSecureKeyHandler.java index 09da501c..49989bd5 100644 --- a/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/handler/ProxyMessageSecureKeyHandler.java +++ b/neutrino-proxy-client/src/main/java/org/dromara/neutrinoproxy/client/handler/ProxyMessageSecureKeyHandler.java @@ -22,6 +22,9 @@ public class ProxyMessageSecureKeyHandler implements ProxyMessageHandler { byte[] decryptedData = SmEncryptUtil.decryptBySm4(secureKey, data); String m = new String(decryptedData); if ("ok".equals(m)) { + // 设置当前链路为安全,之后使用该链路传输的消息均会加密 + Attribute booleanAttribute = ctx.attr(Constants.IS_SECURITY); + booleanAttribute.set(true); log.info("Encrypted link established successfully"); } else { ctx.channel().close(); diff --git a/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/Constants.java b/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/Constants.java index ab831211..6e1751a3 100644 --- a/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/Constants.java +++ b/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/Constants.java @@ -42,6 +42,8 @@ public interface Constants { AttributeKey SECURE_KEY = AttributeKey.newInstance("secure_key"); + AttributeKey IS_SECURITY = AttributeKey.newInstance("is_security"); + AttributeKey LICENSE_ID = AttributeKey.newInstance("license_id"); AttributeKey TARGET_IP = AttributeKey.newInstance("targetIp"); @@ -62,6 +64,7 @@ public interface Constants { interface ProxyDataTypeName { String HEARTBEAT = "HEARTBEAT"; String SECURE_KEY = "SECURE_KEY"; + String IS_SECURITY = "IS_SECURITY"; String AUTH = "AUTH"; String CONNECT = "CONNECT"; String DISCONNECT = "DISCONNECT"; diff --git a/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessageDecoder.java b/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessageDecoder.java index 3fa077d9..3ac525d2 100644 --- a/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessageDecoder.java +++ b/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessageDecoder.java @@ -74,24 +74,34 @@ public class ProxyMessageDecoder extends LengthFieldBasedFrameDecoder { return null; } - int packageLength = in.readInt(); - if (in.readableBytes() < packageLength) { - return null; + Attribute booleanAttribute = ctx.attr(Constants.IS_SECURITY); + Boolean isSecurity = booleanAttribute.get(); + + ByteBuf buf; + + // 考虑isSecurity为null的情况,null的情况也为false + if (isSecurity == true) { + int packageLength = in.readInt(); + if (in.readableBytes() < packageLength) { + return null; + } + + // 获取加密数据 + byte[] encryptedBytes = new byte[packageLength]; + in.readBytes(encryptedBytes); + in.release(); + + // 获取解密密钥 + Attribute secureKeyAttr = ctx.attr(SECURE_KEY); + byte[] secureKey = secureKeyAttr.get(); + // 解密 + byte[] decryptedData = SmEncryptUtil.decryptBySm4(secureKey, encryptedBytes); + + buf = Unpooled.wrappedBuffer(decryptedData); + } else { + buf = in; } - // 获取加密数据 - byte[] encryptedBytes = new byte[packageLength]; - in.readBytes(encryptedBytes); - in.release(); - - // 获取解密密钥 - Attribute secureKeyAttr = ctx.attr(SECURE_KEY); - byte[] secureKey = secureKeyAttr.get(); - // 解密 - byte[] decryptedData = SmEncryptUtil.decryptBySm4(secureKey, encryptedBytes); - - ByteBuf buf = Unpooled.wrappedBuffer(decryptedData); - ProxyMessage proxyMessage = new ProxyMessage(); int frameLength = buf.readInt(); byte type = buf.readByte(); diff --git a/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessageEncoder.java b/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessageEncoder.java index c4eb67e3..a4101121 100644 --- a/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessageEncoder.java +++ b/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessageEncoder.java @@ -56,7 +56,17 @@ public class ProxyMessageEncoder extends MessageToByteEncoder { bodyLength += msg.getData().length; } - ByteBuf buf = Unpooled.buffer(bodyLength); + Attribute booleanAttribute = ctx.attr(Constants.IS_SECURITY); + Boolean isSecurity = booleanAttribute.get(); + + ByteBuf buf; + + // 考虑isSecurity为null的情况,null的情况也为false + if (isSecurity == true) { + buf = Unpooled.buffer(bodyLength); + } else { + buf = out; + } // write the total packet length but without length field's length. buf.writeInt(bodyLength); @@ -75,15 +85,19 @@ public class ProxyMessageEncoder extends MessageToByteEncoder { buf.writeBytes(msg.getData()); } - // 执行加密 - byte[] data = new byte[bodyLength]; - buf.readBytes(data); - // 获取加密密钥 - Attribute secureKeyAttr = ctx.attr(SECURE_KEY); - byte[] secureKey = secureKeyAttr.get(); - // 执行加密 - byte[] encryptedData = SmEncryptUtil.encryptBySm4(secureKey, data); - out.writeByte(encryptedData.length); - out.writeBytes(encryptedData); + // 考虑isSecurity为null的情况,null的情况也为false + if (isSecurity == true) { + // 执行加密 + byte[] data = new byte[bodyLength]; + buf.readBytes(data); + // 获取加密密钥 + Attribute secureKeyAttr = ctx.attr(SECURE_KEY); + byte[] secureKey = secureKeyAttr.get(); + // 执行加密 + byte[] encryptedData = SmEncryptUtil.encryptBySm4(secureKey, data); + out.writeByte(encryptedData.length); + out.writeBytes(encryptedData); + } + } } diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/handler/ProxyMessageAuthHandler.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/handler/ProxyMessageAuthHandler.java index bc33dedd..8ea5f334 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/handler/ProxyMessageAuthHandler.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/handler/ProxyMessageAuthHandler.java @@ -166,6 +166,10 @@ public class ProxyMessageAuthHandler implements ProxyMessageHandler { } } + // 存储状态为非安全,如果客户端响应以下的公钥信息,则在响应中设置为安全 + Attribute booleanAttribute = ctx.attr(Constants.IS_SECURITY); + booleanAttribute.set(false); + // 生成获取SM2密钥对,私钥存入ctx,公钥拼装参数随Auth数据包返回 KeyPairRecord record = SmEncryptUtil.generateSm2KeyPair(); diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/handler/ProxyMessageSecureKeyHandler.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/handler/ProxyMessageSecureKeyHandler.java index 587d548a..c6970675 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/handler/ProxyMessageSecureKeyHandler.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/handler/ProxyMessageSecureKeyHandler.java @@ -56,6 +56,10 @@ public class ProxyMessageSecureKeyHandler implements ProxyMessageHandler { // 发送回去,以示确认 ctx.writeAndFlush(ProxyMessage.buildSecureKeyReturnMessage(encryptedSuccessInfoData)); ctx.flush(); + + // 设置链路状态为安全,之后使用该链路传输的均会加密 + Attribute booleanAttribute = ctx.attr(Constants.IS_SECURITY); + booleanAttribute.set(true); } @Override