依赖引入
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>2.0.26.Final</version>
</dependency>
这个依赖默认是64位的,32位jdk是无法运行的,这里提供一个32位jar连接,系统最低要求win7
https://cloud.189.cn/t/ZRRBvmRzmEnu
生成客户端和服务端密钥
CA 证书
创建CA PSCK1私钥
openssl genrsa -out ca/ca-key1.pem 1024
CA PSCK1转PSCK8私钥
openssl pkcs8 -topk8 -inform PEM -in ca/ca-key1.pem -outform pem -nocrypt -out ca/ca-key.pem
CA私钥 创建CSR请求(此处会要求证书相关信息参数)
openssl req -new -out ca/ca-req.csr -key ca/ca-key.pem -config openssl.cnf
生成CA的X509证书
openssl x509 -req -in ca/ca-req.csr -out ca/ca-cert.pem -signkey ca/ca-key.pem -days 3650
服务端证书
创建服务器PSCK1私钥
openssl genrsa -out server/server-key.pem 1024
服务器 PSCK1转PSCK8私钥
openssl pkcs8 -topk8 -inform PEM -in server/server-key.pem -outform pem -nocrypt -out server/server-pkcs8.pem
服务器私钥 创建CSR请求(此处会要求证书相关信息参数)
openssl req -new -out server/server-req.csr -key server/server-pkcs8.pem -config openssl.cnf
生成服务器的X509证书
openssl x509 -req -in server/server-req.csr -out server/server-cert.pem -signkey server/server-key.pem -CA ca/ca-cert.pem -CAkey ca/ca-key.pem -CAcreateserial -days 3650
客户端证书
创建客户端PSCK1私钥
openssl genrsa -out client/client-key.pem 1024
客户端 PSCK1转PSCK8私钥
openssl pkcs8 -topk8 -inform PEM -in client/client-key.pem -outform pem -nocrypt -out client/client-pkcs8.pem
客户端私钥 创建CSR请求(此处会要求证书相关信息参数)
openssl req -new -out client/client-req.csr -key client/client-pkcs8.pem -config openssl.cnf
生成客户端的X509证书
openssl x509 -req -in client/client-req.csr -out client/client-cert.pem -signkey client/client-key.pem -CA ca/ca-cert.pem -CAkey ca/ca-key.pem -CAcreateserial -days 3650
服务端代码
public class FidsServerChannelInit extends ChannelInitializer<SocketChannel> {
@Resource
FidsServerHandler fidsServerHandler;
public void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addFirst(getSslHandler());
pipeline.addLast(ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP));
pipeline.addLast(ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
pipeline.addLast(new ObjectEncoder());
pipeline.addLast(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(getClass().getClassLoader())));
pipeline.addLast(fidsServerHandler);
}
/**
* 通信加密
*
* @return
*/
private SslHandler getSslHandler() {
try {
InputStream key = new ClassPathResource("cert/server/server-pkcs8.pem").getInputStream();
InputStream cert = new ClassPathResource("cert/server/server-cert.pem").getInputStream();
InputStream ca = new ClassPathResource("cert/ca/ca-cert.pem").getInputStream();
SslContext sslContext = SslContextBuilder.forServer(cert, key)
.trustManager(ca)
.clientAuth(ClientAuth.REQUIRE)
.sslProvider(SslProvider.OPENSSL)
.build();
return sslContext.newHandler(ByteBufAllocator.DEFAULT);
} catch (Exception e) {
log.error("初始化SSL context 错误", e);
}
return null;
}
}
客户端代码
public class FidsClientChannelInit extends ChannelInitializer<SocketChannel> {
@Resource
private FidsClientHandler fidsClientHandler;
@Resource
private PrependClientIdEncoder prependClientIdEncoder;
public static SslHandler getSslHandler() {
try {
InputStream key = new ClassPathResource("cert/client/client-pkcs8.pem").getInputStream();
InputStream cert = new ClassPathResource("cert/client/client-cert.pem").getInputStream();
InputStream ca = new ClassPathResource("cert/ca/ca-cert.pem").getInputStream();
SslContext sslContext = SslContextBuilder.forClient()
.trustManager(ca)
.keyManager(cert, key)
.sslProvider(SslProvider.OPENSSL)
.build();
return sslContext.newHandler(ByteBufAllocator.DEFAULT);
} catch (Exception e) {
log.error("初始化SSL context 错误",e);
}
return null;
}
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast(ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP));
pipeline.addLast(ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
pipeline.addLast(prependClientIdEncoder);
pipeline.addLast(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(getClass().getClassLoader())));
pipeline.addLast(fidsClientHandler);
pipeline.addFirst(getSslHandler());
}
}
后记
不要使用JDK自带的ssl加密,性能很差,以本代码为例会增加3~4秒额外延时。
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!