JDK原生使用數字證書和PKCS#8格式的私鑰完成SSL引擎的初始化。
#使用JDK的SslEngine引擎初始化SslContent
File certChainFile=new File("/home/certs/nginx.crt");
File keyFile=new File("/home/certs/pkcs8_rsa_private_key.pem");
SslContext sslCtx = SslContextBuilder.forServer(certChainFile, keyFile).clientAuth(ClientAuth.NONE).sslProvider(SslProvider.JDK).build();
另外還可以使用OpenSSL模塊來初始化SslContent,據說性能上比JDK的好一些。
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>2.0.26.Final</version>
</dependency>
File certChainFile=new File("/home/certs/nginx.crt");
File keyFile=new File("/home/certs/pkcs8_rsa_private_key.pem");
SslContext sslCtx = SslContextBuilder.forServer(certChainFile, keyFile).clientAuth(ClientAuth.NONE)
.sslProvider(SslProvider.OPENSSL).build();
在netty-tcnative-boringssl-static-jar包內部包含了操作系統的類庫,可以使用jni調用。
把SSLhander放入pipeline的第一個位置,這樣出入的字節流都會通過它進行加密。
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).handler(new LoggingHandler())
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
System.out.println("initChannel:" + ch.localAddress());
ch.pipeline().addLast("ssl", sslCtx.newHandler(ByteBufAllocator.DEFAULT));
//ch.pipeline().addLast("lengthDecoder", new LengthFieldBasedFrameDecoder(2000, 0, 2, 0, 2));
//ch.pipeline().addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
ch.pipeline().addLast("DiscardMsg", new DiscardMsg());
ch.pipeline().addLast(new HeartBeatServerHandler());
}
});
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}