Netty SSL双向验证
1. 环境说明
- 本例使用windows10 + Win64OpenSSL-3_3_0(完整版,不是lite),netty版本4.1.77.Final,JDK-17
- openssl官方推荐合作下载地址:https://slproweb.com/download/Win64OpenSSL-3_3_0.exe
- ${openssl_home}是openssl的安装目录
- 所有命令在${openssl_home}/bin目录下执行
- windows下openssl的配置文件是${openssl_home}/bin/openssl.cfg,linux下是${openssl_home}/bin/openssl.conf,注意替换后缀名
- 需要手动按照openssl.cfg的配置创建好各种目录、文件
2. 生成证书
2.1. 创建根证书 密钥+证书
openssl genrsa -des3 -out demoCA/private/ca.key 4096
openssl req -new -x509 -days 3650 -key demoCA/private/ca.key -out demoCA/certs/ca.crt
2.2. 生成请求证书密钥
openssl genrsa -des3 -out demoCA/private/server.key 2048
openssl genrsa -des3 -out demoCA/private/client.key 2048
2.3. 生成csr请求证书
openssl req -new -key demoCA/private/server.key -out demoCA/certs/server.csr -config openssl.cfg
openssl req -new -key demoCA/private/client.key -out demoCA/certs/client.csr -config openssl.cfg
2.4. ca证书对server.csr、client.csr签发生成x509证书
openssl x509 -req -days 3650 -in demoCA/certs/server.csr -CA demoCA/certs/ca.crt -CAkey demoCA/private/ca.key -CAcreateserial -out demoCA/certs/server.crt
openssl x509 -req -days 3650 -in demoCA/certs/client.csr -CA demoCA/certs/ca.crt -CAkey demoCA/private/ca.key -CAcreateserial -out demoCA/certs/client.crt
2.5. 请求证书PKCS#8编码
openssl pkcs8 -topk8 -in demoCA/private/server.key -out demoCA/private/pkcs8_server.key -nocrypt
openssl pkcs8 -topk8 -in demoCA/private/client.key -out demoCA/private/pkcs8_client.key -nocrypt
2.6. 输出文件
server端:ca.crt、server.crt、pkcs8_server.key
client端:ca.crt、client.crt、pkcs8_client.key
3. Java代码
3.1. Server端
- ServiceMain.java
public class ServiceMain implements CommandLineRunner {
@Value("${netty.host}")
private String host;
@Value("${netty.port}")
private int port;
@Resource
private NettyServer nettyServer;
public static void main(String[] args) {
SpringApplication.run(ServiceMain.class, args);
}
@Override
public void run(String... args) throws Exception {
InetSocketAddress address = new InetSocketAddress(host, port);
ChannelFuture channelFuture = nettyServer.bind(address);
Runtime.getRuntime().addShutdownHook(new Thread(() -> nettyServer.destroy()));
channelFuture.channel().closeFuture().syncUninterruptibly();
}
}
- NettyServer.java
package cn.a.service.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.ssl.ClientAuth;
import io.netty.handler.ssl.SslContext;