《HTTP 中的“握手”:从 TCP 到 TLS 的安全通信之旅》
🧠 第四篇:《HTTP 中的“握手”:从 TCP 到 TLS 的安全通信之旅》
前一篇我们讲到,浏览器和服务器通过 TCP 三次握手 建立连接,之后 HTTP 报文才能传输。
但现实中,大多数网站已经从
http://升级成了https://。为什么?
因为 HTTP 是明文传输,别人可以轻易窃听你的数据,而 HTTPS 则通过 TLS 加密握手,让传输安全可靠。今天,我们要彻底揭开这两个“握手”的神秘面纱。
一、为什么要握手?
“握手”是通信双方确认身份和建立规则的过程。
想象一下你给陌生人打电话:
“喂,你是百度吗?”
“是的,我是。你是 Joon 吗?”
“对,那我们开始聊吧。”
在计算机世界里,这个确认过程就是“握手”。
TCP 握手确保双方能可靠通信,而 TLS 握手确保通信安全可加密。
二、第一层握手:TCP 三次握手(回顾 + 图解)
我们先快速回顾一下:
客户端 服务器| ----------- SYN ----------> || <-------- SYN + ACK ------- || ----------- ACK ----------> |
📦 说明:
- 客户端请求连接(SYN)
- 服务器确认并回应(SYN + ACK)
- 客户端确认(ACK)
✅ 完成后,TCP 通道建立成功,可以双向通信。
但注意,此时数据仍是明文传输。
三、为什么需要第二层握手(TLS)?
HTTP 是“裸奔”的:
- 登录密码、银行卡号、隐私数据都是明文;
- 任何人监听网络(如公共 WiFi)都能看到;
- 也无法验证服务器的真实性(可能被伪造网站冒充)。
所以我们需要第二层保护:TLS 握手(Transport Layer Security)
👉 TLS 是在 TCP 之上的“安全协议”,它通过加密、证书和密钥协商,让通信内容安全。
四、HTTPS 握手(TLS 1.2版本)流程详解
TLS 握手是在 TCP 通道建立后进行的。
完整过程如下👇
客户端 服务器| ---- ClientHello ----> | ①| <---- ServerHello ---- | ②| <---- Certificate ---- | ③| ---- ClientKeyExchange --> | ④| ---- ChangeCipherSpec ---> | ⑤| ---- EncryptedFinished --> | ⑥| <---- ChangeCipherSpec --- | ⑦| <---- EncryptedFinished -- | ⑧
🧩 第一步:ClientHello
客户端(浏览器)首先发出:
- 支持的 TLS 版本
- 支持的加密算法列表
- 一个随机数(client random)
📦 示例:
TLSv1.2
Cipher Suites: AES256, RSA, ECDHE
Random: 3A B2 9F 1E ...
🧩 第二步:ServerHello
服务器回应:
- 选择一个加密算法
- 发送另一个随机数(server random)
📦 示例:
Cipher Suite: ECDHE-RSA-AES256
Random: F9 2C 7E D3 ...
🧩 第三步:Certificate
服务器发送自己的 数字证书(由 CA 机构签发),里面包含:
- 服务器的公钥(Public Key)
- 域名
- 有效期
- 签发机构(如 DigiCert、Let’s Encrypt)
- 数字签名
💡浏览器此时会验证证书:
- 是否由可信 CA 签发?
- 域名是否匹配?
- 是否过期?
如果验证通过,浏览器确认它在和真正的百度通信。
🧩 第四步:ClientKeyExchange
客户端生成一个预主密钥(Pre-Master Secret),
用服务器的公钥加密后发送过去。
📦 意思是:
“我用你的公钥锁上这把钥匙,只能你能打开。”
🧩 第五步:ChangeCipherSpec(切换加密模式)
双方用:
client random + server random + pre-master secret
计算出会话密钥(session key),并宣布:
“从现在开始,我们所有通信都加密了。”
🧩 第六、七、八步:加密通信开始!
从这一步起:
- 浏览器和服务器都用相同的对称密钥加密/解密内容;
- 数据安全传输;
- 外人即使拦截,也只能看到加密后的乱码。
五、HTTPS 握手图解版(简化)
┌──────────────┐ ┌──────────────┐
│ 浏览器 │ │ 服务器 │
└──────────────┘ └──────────────┘│ ClientHello(支持算法+随机数) ││───────────────────────────────▶││◀───────────────────────────────││ ServerHello + Certificate + Random ││───────────────────────────────▶││ 验证证书合法性 ││───────────────────────────────▶││ 生成 Pre-Master Secret,加密发送 ││───────────────────────────────▶││ 双方生成会话密钥 ││ 切换为加密通信 │
六、真实案例:用浏览器查看 HTTPS 握手信息
你可以自己观察整个过程👇
-
打开 Chrome →
https://www.baidu.com -
按下
F12→ 选择 Network(网络) -
点击第一个请求 → 选择 Security(安全)
-
你会看到:
- TLS 版本(如 TLS 1.3)
- 加密算法(如 ECDHE-RSA-AES128-GCM-SHA256)
- 证书颁发机构(CA)
✅ 浏览器 padlock 🔒 图标亮起
代表“证书有效 + 通信加密 + 安全连接”
七、TLS 1.3 的变化(更快更安全)
TLS 1.3 对比 1.2:
| 特点 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| 握手次数 | 多达 6~8 次 | 最少只需 1-RTT |
| 加密算法 | RSA、AES 等 | 更现代的 ECDHE |
| 安全性 | 较弱 | 强制前向保密 |
| 性能 | 较慢 | 更快,减少延迟 |
💡 “前向保密”意味着即使黑客拿到你的密钥,也无法解密之前的通信内容。
八、加密通信效果演示
未加密(HTTP):
POST /login
username=joon&password=123456
加密后(HTTPS):
Encrypted Application Data
Length: 312
Data: 3A 9F D2 7B E1 ...
即使被窃听,也只会看到一堆无法破解的密文。
九、总结
| 类型 | 握手对象 | 目的 | 是否加密 |
|---|---|---|---|
| TCP 三次握手 | 浏览器 ↔ 服务器 | 建立连接 | ❌ |
| TLS 握手 | 浏览器 ↔ 服务器 | 建立安全加密通信 | ✅ |
HTTP + TCP → 数据能传
HTTPS + TCP + TLS → 数据能“安全地传”
🔚 十、下一篇预告:第五篇《HTTP 常见状态码与错误解析》
你看到过“404 页面未找到”吧?
或者“500 服务器出错”?下一篇我们将带你系统讲解 HTTP 状态码:
- 1xx、2xx、3xx、4xx、5xx 各自代表什么?
- 为什么有的跳转是 301,有的是 302?
- 如何在实际开发中“优雅地处理错误响应”?
- 附带真实请求案例分析(抓包 + Chrome DevTools)
