diff --git a/src/main/java/com/muyu/common/Config.java b/src/main/java/com/muyu/common/Config.java index 850a6d7..351046e 100644 --- a/src/main/java/com/muyu/common/Config.java +++ b/src/main/java/com/muyu/common/Config.java @@ -30,6 +30,11 @@ public class Config { */ public static ChannelHandlerContext ctx; + /** + * 加密方式 + */ + public static final String[] CIPHER_ARRAY = {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"}; + /** * 车辆VIN */ diff --git a/src/main/java/com/muyu/netty/client/NettyClientInit.java b/src/main/java/com/muyu/netty/client/NettyClientInit.java index 2040721..8569ec3 100644 --- a/src/main/java/com/muyu/netty/client/NettyClientInit.java +++ b/src/main/java/com/muyu/netty/client/NettyClientInit.java @@ -4,6 +4,7 @@ package com.muyu.netty.client; import com.muyu.common.Common; import com.muyu.common.Config; import com.muyu.netty.bean.NettyClientBean; +import com.muyu.netty.ssl.SslContextFactory; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; @@ -15,10 +16,14 @@ import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; +import io.netty.handler.ssl.SslHandler; import io.netty.handler.timeout.IdleStateHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; + /** * @author 牧鱼 @@ -45,40 +50,47 @@ public class NettyClientInit { try { Bootstrap b = new Bootstrap(); mClientHandler = new NettyClientHandler(); - b.group(Config.workerGroup).channel(NioSocketChannel.class) - // KeepAlive - .option(ChannelOption.SO_KEEPALIVE, true) - // Handler - .handler(new ChannelInitializer() { - - @Override - protected void initChannel(SocketChannel channel) throws Exception { + b.group(Config.workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.handler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel channel) throws Exception { +// SSLContext sslCtx = SslContextFactory.getServerContext(); +// SSLEngine sslEngine = sslCtx.createSSLEngine(); + //设置加密套件 +// sslEngine.setEnabledCipherSuites(Config.CIPHER_ARRAY); +// sslEngine.setUseClientMode(false); +// sslEngine.setNeedClientAuth(true); +// channel.pipeline().addFirst("SslEstablish", new SslHandler(sslEngine)); // SSLEngine sslEngine = sslContext.createSSLEngine(); // sslEngine.setUseClientMode(false); //服务器端模式 // sslEngine.setNeedClientAuth(false); //不需要验证客户端 // channel.pipeline().addFirst("ssl", new SslHandler(sslEngine)); - //分包器 - channel.pipeline().addLast( - new DelimiterBasedFrameDecoder( - 1024, - Unpooled.copiedBuffer(Config.DATA_PACK_SEPARATOR.getBytes() - ) - ) - ); - // 心跳 - channel.pipeline().addLast("HBeat", new IdleStateHandler( - 20, - 10, 0)); - //编码器 - channel.pipeline().addLast("encoder", new StringEncoder()); - //解码器 - channel.pipeline().addLast("decoder", new StringDecoder()); + //分包器 + channel.pipeline().addLast( + new DelimiterBasedFrameDecoder( + 1024, + Unpooled.copiedBuffer(Config.DATA_PACK_SEPARATOR.getBytes() + ) + ) + ); + // 心跳 + channel.pipeline().addLast("HBeat", new IdleStateHandler( + 20, + 10, 0)); + //编码器 + channel.pipeline().addLast("encoder", new StringEncoder()); + //解码器 + channel.pipeline().addLast("decoder", new StringDecoder()); - //处理器 - channel.pipeline().addLast(mClientHandler); - } - }); + //处理器 + channel.pipeline().addLast(mClientHandler); + } + }); + // KeepAlive + // Handler future = b.connect(nettyClientBean.getHost(), nettyClientBean.getPort()).sync(); if (future.isSuccess()) { log.info("Client,链接服务端成功"); diff --git a/src/main/java/com/muyu/netty/operate/NettyClientMsg.java b/src/main/java/com/muyu/netty/operate/NettyClientMsg.java index 03005d5..0eeee67 100644 --- a/src/main/java/com/muyu/netty/operate/NettyClientMsg.java +++ b/src/main/java/com/muyu/netty/operate/NettyClientMsg.java @@ -43,7 +43,6 @@ public class NettyClientMsg { * 销毁netty */ public static void destroy(){ - log.info("发送断开连接消息:"+Config.NETTY_CLOSE); sendMsg(Config.NETTY_WILL_CLOSE + Config.VIN); Config.ctx = null; } diff --git a/src/main/java/com/muyu/netty/ssl/SslContextFactory.java b/src/main/java/com/muyu/netty/ssl/SslContextFactory.java new file mode 100644 index 0000000..f49b7c2 --- /dev/null +++ b/src/main/java/com/muyu/netty/ssl/SslContextFactory.java @@ -0,0 +1,73 @@ +package com.muyu.netty.ssl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyStore; + +public class SslContextFactory { + + private static final Logger log = LoggerFactory.getLogger(SslContextFactory.class); + + private static final String PROTOCOL = "TLS"; + + private static volatile SSLContext SERVER_CONTEXT = null; + + private static final String DEFAULT_PROPERTIES = "application.properties"; + + private static final String SSL_KEY_STORE_TYPE = "JKS"; + + private static final String SSL_KEY_STORE_PASSWORD = "vehicle"; + + private static final String SSL_KEY_STORE = System.getProperty("user.dir")+ File.separator + "src" +File.separator + "main" + File.separator + + "resources" + File.separator+"ssl"+File.separator+"cVehicleChat.jks"; + + private static void init(){ + InputStream keyStore = null; + InputStream trustStore = null; + try { + //初始化keyManagerFactory + KeyStore ks = KeyStore.getInstance(SSL_KEY_STORE_TYPE); + keyStore = new FileInputStream(SSL_KEY_STORE); + ks.load(keyStore, SSL_KEY_STORE_PASSWORD.toCharArray()); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(ks, SSL_KEY_STORE_PASSWORD.toCharArray()); + //初始化TrustManagerFacotry + KeyStore ts = KeyStore.getInstance(SSL_KEY_STORE_TYPE); + trustStore = new FileInputStream(SSL_KEY_STORE); + ts.load(trustStore, SSL_KEY_STORE_PASSWORD.toCharArray()); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(ts); + //生成SSLContext + SERVER_CONTEXT = SSLContext.getInstance(PROTOCOL); + SERVER_CONTEXT.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + } catch (IOException e) { + throw new RuntimeException(e.getMessage(), e); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } finally { + try { + if (null != keyStore) { + keyStore.close(); + } + if (null != trustStore) { + trustStore.close(); + } + } catch (IOException e) { } + } + } + + static { + init(); + } + public static SSLContext getServerContext() { + return SERVER_CONTEXT; + } +} diff --git a/src/main/resources/ssl/cVehicleChat.cer b/src/main/resources/ssl/cVehicleChat.cer new file mode 100644 index 0000000..c108c4a Binary files /dev/null and b/src/main/resources/ssl/cVehicleChat.cer differ diff --git a/src/main/resources/ssl/cVehicleChat.jks b/src/main/resources/ssl/cVehicleChat.jks new file mode 100644 index 0000000..4ee669d Binary files /dev/null and b/src/main/resources/ssl/cVehicleChat.jks differ diff --git a/src/main/resources/ssl/sVehicleChata.cer b/src/main/resources/ssl/sVehicleChata.cer new file mode 100644 index 0000000..1beb826 Binary files /dev/null and b/src/main/resources/ssl/sVehicleChata.cer differ diff --git a/src/main/resources/ssl/sVehicleChata.jks b/src/main/resources/ssl/sVehicleChata.jks new file mode 100644 index 0000000..4592800 Binary files /dev/null and b/src/main/resources/ssl/sVehicleChata.jks differ