Netty传输链路中,使用TLSv1.3传输层安全协议进行加密如何实现
之前做的一个新项目,是基于我们当前的项目+需求方提出的几点要求
主要就是通过netty建立tcp链路连接,然后通过链路传输数据
新增加的点就是:
1、TCP传输采用TLSv1.3协议进行加密(我们是客户端,对方是服务端)
2、需要的证书服务端提供
3、netty使用最新版本
4、使用安全的密码套件
一、前期准备工作:
1、依赖版本的确定, JDK21+Netty4.1.109.Final
2、服务端提供的证书,让运维放到服务器上
3、加密套件确定,TLS1.3支持的加密套件如下:
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
好了,接下来就开始正式的代码吧!
二、实现逻辑
//TLS1.3支持的加密套件
private List<String> cipherSuites = Arrays.asList(
"TLS_AES_128_GCM_SHA256",
"TLS_AES_256_GCM_SHA384",
"TLS_CHACHA20_POLY1305_SHA256"
);
//1、加载证书 cert.crt是服务端提供的证书
File certFile = new File("path/to/cert.crt");
//2、创建SslContext
//如果是客户端就使用SslContextBuilder.forClient(),服务端就使用 SslContextBuilder.forServer()
SslContext sslCtx = SslContextBuilder.forClient()
//设置支持的协议
.protocols("TLS1.3")
//开启startTls,默认是关闭的
.startTls(true)
//设置密码套件
.ciphers(cipherSuites)
//信任管理器
.trustManager(certFile)
.build();
//3、添加处理器
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
// 从 SslContext 获得一个新的SslEngine
SSLEngine sslEngine = sslCtx.newEngine(ch.alloc());
// 添加ssl处理器为第一个处理器,确保其它ChannelHandler的逻辑应用到数据后加密才发生
p.addFirst("ssl",sslCtx.newHandler(sslEngine));
// netty的处理器,打印tls日志
p.addLast(new LoggingHandler(LogLevel.DEBUG));
// 自定义的业务处理器
p.addLast(new YourHandler());
}
});
三、注意点:在Netty中启用TLSv1.3协议,需要确保几个关键点:
1、JVM版本:java版本必须至少是JDK11或者更高,因为TLSv1.3是在Java11中引入的
2、Netty版本:Netty从4.1.46Final版本开始支持TLSv1.3,所以Netty版本至少是这个版本或者更新的版本
3、配置SSLContext:在Netty中,需要创建一个SSLContext实例来配置TLS
4、选用加密套件时,需要使用TLSv1.3 或TLSv1.2 协议支持的加密套件,如果不是支持的加密套件,也会导致netty连接失败
(我最开始百度出来的的加密套件都是TLSv1.2支持的,最后测试时,连接就失败)
四、相关依赖版本关系
代码好实现,这个项目耗时的主要是升级版本,使用JDK21+Netty4.1.109.Final后,与其它依赖的冲突关系,一启动就报错,让人头麻
<java.version>21</java.version>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<artifactId>lindorm-all-client</artifactId>
<version>2.2.0-alpha.1</version>
<artifactId>apollo-client</artifactId>
<version>2.2.0</version>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.5</version>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.25.0</version>
<artifactId>spring-kafka</artifactId>
<version>3.1.4</version>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<artifactId>netty-all</artifactId>
<version>4.1.109.Final</version>
<artifactId>hutool-all</artifactId>
<version>5.8.25</version>
以上是我简单整理的一部分依赖及版本信息,其它的几个版本是业务需要,我就不弄了
好了,终于整理好了,以后再遇到类似问题就不至于晕头转向了,哈哈
附:maven仓库地址 https://mvnrepository.com
如果想看你使用的依赖都有哪些版本,就在仓库里搜就行
使用tips:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.25</version>
</dependency>
例如,我想看hutool-all都有哪些版本,搜索地址就是
https://mvnrepository.com/artifact/cn.hutool/hutool-all