当前位置: 首页>后端>正文

即时通讯开发Netty原理介绍

作为一个高性能的NIO通信框架,基于Netty的行业应用非常广泛,不同的行业、不同的应用场景,面临的安全挑战也不同,下面我们根据Netty的典型应用场景,分析下Netty面临的安全挑战。

仅限内部使用的RPC通信框架

随着业务的发展,网站规模的扩大,传统基于MVC的垂直架构已经无法应对业务的快速发展。需要对数据和业务进行水平拆分,基于RPC的分布式服务框架成为最佳选择。

业务水平拆分之后,内部的各个模块需要进行高性能的通信,传统基于RMI和Hession同步阻塞式通信已经无法满足性能和可靠性要求。因此,高性能的NIO框架成为构建分布式服务框架的基石。

高性能的RPC框架,各模块之间往往采用长连接通信,通过心跳检测保证链路的可靠性。由于RPC框架通常是在内部各模块之间使用,运行在授信的内部安全域中,不直接对外开放接口。因此,不需要做握手、黑白名单、SSL/TLS等,正所谓是“防君子不防小人”。

即时通讯开发Netty原理介绍,第1张

在这种应用场景下,Netty的安全性是依托企业的防火墙、安全加固操作系统等系统级安全来保障的,它自身并不需要再做额外的安全性保护工作。

如果使用Netty做RPC框架或者私有协议栈,RPC框架面向非授信的第三方开放,例如将内部的一些能力通过服务对外开放出去,此时就需要进行安全认证,如果开放的是公网IP,对于安全性要求非常高的一些服务,例如在线支付、订购等,需要通过SSL/TLS进行通信。

对第三方开放的通信框架的接口调用存在三种场景:

在企业内网,开放给内部其它模块调用的服务,通常不需要进行安全认证和SSL/TLS传输;

在企业内网,被外部其它模块调用的服务,往往需要利用IP黑白名单、握手登陆等方式进行安全认证,认证通过之后双方使用普通的Socket进行通信,如果认证失败,则拒绝客户端连接;

开放给企业外部第三方应用访问的服务,往往需要监听公网IP(通常是防火墙的IP地址),由于对第三方服务调用者的监管存在诸多困难,或者无法有效监管,这些第三方应用实际是非授信的。为了有效应对安全风险,对于敏感的服务往往需要通过SSL/TLS进行安全传输。

作为高性能、异步事件驱动的NIO框架,Netty非常适合构建上层的应用层协议,相关原理,

由于绝大多数应用层协议都是公有的,这意味着底层的Netty需要向上层提供通信层的安全传输,也就是需要支持SSL/TLS。即时通讯开发https://www.wecloud.cn/

即时通讯开发Netty原理介绍,第2张

JDK的安全类库提供了javax.net.ssl.SSLSocket和javax.net.ssl.SSLServerSocket类库用于支持SSL/TLS安全传输,对于NIO非阻塞Socket通信,JDK并没有提供现成可用的类库简化用户开发。Netty通过JDK的SSLEngine,以SslHandler的方式提供对SSL/TLS安全传输的支持,极大的简化了用户的开发工作量,降低开发难度。

对于Netty默认提供的HTTP协议,Netty利用SslHandler,同样支持HTTPS协议。

单向认证,即客户端只验证服务端的合法性,服务端不验证客户端。下面我们通过Netty的SSL单向认证代码开发来掌握基于Netty的SSL单向认证。

首先,利用JDK的keytool工具,Netty服务端依次生成服务端的密钥对和证书仓库、服务端自签名证书。

生成Netty服务端私钥和证书仓库命令:

keytool -genkey -alias securechat -keysize 2048 -validity

365 -keyalg RSA -dname "CN=localhost" -keypass sNetty

-storepass sNetty -keystore sChat.jks

生成Netty服务端自签名证书:

keytool -export -alias securechat -keystore sChat.jks -storepass sNetty -file sChat.cer

生成客户端的密钥对和证书仓库,用于将服务端的证书保存到客户端的授信证书仓库中,命令如下:

keytool -genkey -alias smcc -keysize 2048 -validity 365

-keyalg RSA -dname "CN=localhost" -keypass cNetty

-storepass cNetty -keystore cChat.jks

随后,将Netty服务端的证书导入到客户端的证书仓库中,命令如下:

keytool -import -trustcacerts -alias securechat -file sChat.cer -storepass cNetty -keystore cChat.jks

上述工作完成之后,我们就开始编写SSL服务端和客户端的代码,下面我们对核心代码进行讲解。首先看服务端的代码,在TCP链路初始化的时候,创建SSLContext并对其进行正确的初始化,下面我们对SSLContext的创建进行讲解。

SSL单向认证的过程总结如下:

SSL客户端向服务端传送客户端SSL协议的版本号、支持的加密算法种类、产生的随机数,以及其它可选信息;

服务端返回握手应答,向客户端传送确认SSL协议的版本号、加密算法的种类、随机数以及其它相关信息;

服务端向客户端发送自己的公钥;

客户端对服务端的证书进行认证,服务端的合法性校验包括:证书是否过期、发行服务器证书的CA是否可靠、发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”、服务器证书上的域名是否和服务器的实际域名相匹配等;

客户端随机产生一个用于后面通讯的“对称密码”,然后用服务端的公钥对其加密,将加密后的“预主密码”传给服务端;

服务端将用自己的私钥解开加密的“预主密码”,然后执行一系列步骤来产生主密码;

客户端向服务端发出信息,指明后面的数据通讯将使用主密码为对称密钥,同时通知服务器客户端的握手过程结束;

服务端向客户端发出信息,指明后面的数据通讯将使用主密码为对称密钥,同时通知客户端服务器端的握手过程结束;

SSL的握手部分结束,SSL安全通道建立,客户端和服务端开始使用相同的对称密钥对数据进行加密,然后通过Socket进行传输。


https://www.xamrdz.com/backend/34z1941317.html

相关文章: