前言
本文整理了:
- TLS 握手的每一步
- 对称加密 vs 非对称加密
- Netty 如何支持 wss:// 与浏览器加密通信
- 客户端的加密是谁做的
- 业务数据加密的时机
一、TLS 是什么?它和 HTTPS、wss:// 的关系
- TLS:负责加密
- HTTPS = HTTP + TLS
- wss:// = WebSocket + TLS
TLS 是一个通用的加密层,不属于 HTTP,也不属于 WebSocket。
浏览器 →(TLS 加密)→ 服务器
二、TLS 握手的完整流程
下面是现代 TLS 1.2 流程(含 RSA/ECDHE) :
1. Client
浏览器或客户端发送:
- TLS 版本
- 随机数 random1
- 支持的加密算法列表
- SNI(域名)
2. Server
服务器返回:
- TLS 版本
- 随机数 random2
- 选择的加密算法(如 TLS_ECDHE_RSA_AES_128_GCM_SHA256)
- 服务器证书(含公钥)
3. 验证证书(由浏览器做或客户端)
浏览器检查:
- 是否被 CA 签名
- 域名是否匹配
- 是否过期
失败则显示 HTTPS 红色警告。
4. 密钥交换
根据加密算法不同:
- RSA:客户端用服务器公钥加密 pre_master_key
- ECDHE:双方交换椭圆曲线公钥,计算共享密钥
5. 生成对称密钥(Session Key)
双方使用:
random1 + random2 + pre_master_key
生成最终用于 数据加密 的对称密钥。
6. Change Cipher Spec
双方通知:“我接下来用 Session Key 加密了”。
7. Finished(第一个被加密的包)
握手完成。
此后:
所有业务数据全部使用对称加密
三、对称加密 vs 非对称加密
非对称加密(RSA/ECDSA/ECDHE)
特点:
- 公钥加密,私钥解密
- 慢
- 只用于 握手阶段(交换对称密钥)
对称加密(AES)
特点:
- 加解密速度快
- 用在 业务数据传输阶段
TLS 的黄金组合:
握手用非对称,传输用对称。
四、Netty 如何支持 wss://
Netty 的 wss:// 底层就是:
TCP → TLS → WebSocket
实现步骤:
1. 创建 SSLContext(加载证书)
SslContext sslContext = SslContextBuilder.forServer(certChainFile, privateKeyFile).build();
2. 在 pipeline 前面加一个 SslHandler
pipeline.addLast(sslContext.newHandler(ch.alloc()));
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
注意:
- WebSocket 握手是在明文 HTTP 中进行
- 但当你使用 wss:// 时 HTTP 部分也是被 TLS 加密的
浏览器连接:
wss://example.com/ws
即可自动通过 TLS 进行加密通信。
五、客户端的加密工作是谁做的?
1. 浏览器中的 TLS 由谁做?
由浏览器内部的 TLS 库完成:
- Chrome:BoringSSL
- Firefox:NSS
- Safari:苹果系统 TLS
程序员完全无法干预加密流程。
2. 应用层(JS)看到的永远是明文
例如:
ws.send("hello");
发送的是明文字符串。
真正加密是在:
- 浏览器 TLS 层
- 系统 Socket 层
你的 JS 根本接触不到加密细节。
六、业务数据加密的执行时机
TLS 握手完成后,后续所有应用数据加密由 TLS 记录层 自动完成。
1. 业务发送数据的加密流程
当:
ws.send("hello");
时,流程如下:
- JS 生成明文
"hello" - 浏览器将它交给 TLS 层
- TLS 使用协商好的对称密钥 AES 自动加密
- 加密后的二进制数据才写入 TCP
业务层完全无法参与。
2. 服务端收到数据的解密流程
Netty 服务器收到 TLS 加密数据包:
- SslHandler 自动执行解密
- 解密后的 WebSocket 帧进入 pipeline
- 业务 Handler 看到的永远是明文
示例:
channelRead(ctx, msg) // msg 已经是明文
3. TLS 与 WebSocket 的关系
WebSocket 不负责加密。
流程如下:
WebSocket 明文帧
↓
TLS 自动加密
↓
TCP 发送
因此:
业务数据的加密解密时机在 TLS 层,而不是在 WebSocket 层,更不是在业务代码中。
七、总结
- TLS 是所有 HTTPS/wss:// 加密的核心
- 握手阶段用 RSA/ECDHE 非对称加密换取对称密钥
- 业务数据阶段全部使用对称加密(AES/ChaCha20)
- 浏览器负责加密,程序员完全不用管
- Netty 通过 SslHandler 实现 wss://
- 业务代码看到的永远是明文,TLS 自动负责加密/解密