【杂谈】关于SSL/TLS通信加密

什么是 SSL/TLS 协议?它位于哪一层?

SSL(Secure Sockets Layer)和 TLS(Transport Layer Security)是用于保护网络通信安全的加密协议。

它们通过加密、身份验证和完整性检查,确保数据在传输过程中不被窃取或篡改。

SSL/TLS 协议位于传输层和应用层之间,通常用于增强 HTTP、FTP、SMTP 等应用层协议的安全性。

它需要什么?

要建立 SSL/TLS 连接,需要以下几个关键组件:

  • 服务端证书:由公钥和私钥组成的数字证书,用于证明服务器的身份,并在握手阶段传给客户端。
  • 客户端配置:如果服务器使用由受信任的证书颁发机构(CA)签发的证书,客户端通常无需额外配置,因为它会自动信任这些证书。如果服务器使用自签名证书,则客户端需要手动配置证书文件地址,以验证服务器的身份。

自定义协议如何使用它?

对于自定义协议(如使用 Netty 构建的应用),可以通过 Netty 提供的 SslHandler 来启用 SSL/TLS 支持。

你只需在管道(pipeline)中添加 SslHandler,并将其放在最前面,以确保数据在进入其他处理器之前被加密或解密。

客户端配置
只要配置为客户端模式,并加载受信任的证书。如果使用的是公共CA签发的证书,客户端通常不需要额外配置证书
复制代码
public class NettySslClientInitializer extends ChannelInitializer<SocketChannel> {

    private final SslContext sslCtx;

    public NettySslClientInitializer() throws SSLException {
        // 创建一个用于客户端的 SslContext
        sslCtx = SslContextBuilder.forClient().build();
    }

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        // 将 SslHandler 添加到 pipeline 中
        ch.pipeline().addFirst(sslCtx.newHandler(ch.alloc()));
        // 添加其他处理器
    }
}
复制代码

服务端配置

在服务端,SslContext需要配置为服务端模式,并加载服务端的证书和私钥。

复制代码
public class NettySslServerInitializer extends ChannelInitializer<SocketChannel> {

    private final SslContext sslCtx;

    public NettySslServerInitializer() throws SSLException {
        // 创建一个用于服务端的 SslContext,加载服务端的证书和私钥
        sslCtx = SslContextBuilder.forServer(new File("server.crt"), new File("server.key")).build();
    }

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        // 将 SslHandler 添加到 pipeline 中
        ch.pipeline().addFirst(sslCtx.newHandler(ch.alloc()));
        // 添加其他处理器
    }
}
复制代码

是否会影响上层的粘拆包处理?

不会。SSL/TLS 层在数据到达应用层之前已经完成了解密处理,因此对上层的业务逻辑影响较小。

上层接收到的数据就像来自普通的未加密连接一样,可以正常进行粘包和拆包处理。

SSL/TLS 如何从字节流中提取数据?

SSL/TLS 协议与 TCP 类似,使用报头信息来描述数据块的长度和其他元数据。每个加密的数据块都会包含一个 TLS 记录头部,这样接收端可以根据头部信息准确地解析出每个数据块的长度,并对其进行解密和校验。

因此,SSL/TLS 协议自身也处理了粘包和拆包的问题。

 

需要额外的端口吗?

严格来说,SSL/TLS 本身不要求使用额外的端口。

然而,许多应用通常在使用加密通信时,会开设一个单独的端口来处理加密流量。例如,HTTP 使用端口 80,而 HTTPS 使用端口 443。这种方式允许应用同时支持加密和未加密的通信,未加密端口通常用于内部通信,而加密端口用于外部通信,以确保安全。

额外的开销有哪些?

SSL/TLS 的额外开销主要体现在以下几个方面:

  • CPU 开销:加密和解密过程需要消耗计算资源,特别是在使用强大的加密算法时。
  • 网络开销:每个加密的数据包都有额外的报头和可能的填充字节,以确保数据块大小适配加密算法的要求。
  • 握手延迟:建立 SSL/TLS 连接时,握手过程涉及多次往返的通信,这会增加连接建立的时间。

除了这些,还有一个影响,那就是无法使用零拷贝技术。使用SSL/TLS就不能使用sendfile 了,因为数据必须被载入用户区内存进行加密处理。

因此,对于对网络吞吐量有严格要求的应用,非必要不开启SSL/TLS

那什么时候需要开启呢?

是否开启 SSL/TLS 主要取决于服务的性质、客户端群体、开放程度和通信内容。

  • 内部服务:如果服务是供内部应用使用的(如 Kafka、Redis),通常部署在内网,且有防火墙限定访问 IP 范围,SSL/TLS 可以选择不开启。
  • 外部服务:如果服务面向广泛的客户,且需要在开放网络中使用,建议开启 SSL/TLS 以确保通信安全。

有了SSL/TLS还需要鉴权吗?

这取决于应用层的需求。SSL/TLS 的鉴权主要用于确认客户端和服务端是否能够建立安全的连接。但应用层是否需要额外的鉴权,则取决于具体的应用需求。

以 HTTPS 网站为例,如果是一个仅用于展示内容的门户网站,通常不需要额外的登录鉴权。

然而,对于交互型网站,当用户需要访问或修改个人数据时,登录鉴权是必要的,以确保只有授权用户可以进行此类操作。

开销有办法优化吗?

硬件加速器。可以给对外开放的网关服务器安装硬件加速器。

一方面硬件加速器将加解密的操作从CPU移动到专用的加速卡上,从而释放CPU资源,使其能够专注于其他应用任务。

另一方面它本身专为加解密操作进行优化,处理速度比CPU更快。

posted @   猫毛·波拿巴  阅读(43)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示