适用读者:会调接口但说不清"HTTPS 到底保护了什么"的人;被证书报错拦住过的人。
前置:S02-B01(分层)、S02-B04(可靠传输)。
实测环境:OpenSSL 3.x / curl 8.x / Ubuntu 24.04.1;证书链与握手为 2026-11-05 实测(目标:clxhxhhr.top)。
覆盖旧文:A-1036(HTTPS 和 HTTP 的区别,85 点)、A-488(HTTPS 入门,35 点)= 120 点。
覆盖扩展:E-S02-011(TLS 1.3 握手)、E-S02-012(证书链与 SNI)。
上一篇:S02-B05 · 粘包与拆包:应用层为什么必须自己划边界
下一篇:S02-B07 · WebSocket、SSE、长轮询。
1. 一句话结论
HTTPS = HTTP + TLS。加密发生在 TCP 之上、HTTP 之下——它保护的是"传输通道",不是"应用数据本身"。
HTTP 报文(明文,你自己加密不了的部分)
│
TLS 记录层(加密在这里发生:对称加密 + 完整性校验)
│
TCP(可靠、有序)
│
IP
这条分层位置决定了两件事:
| 事实 | 后果 |
|---|---|
| 加密在传输层之上 | 中间人(路由器、代理、运营商)看不到内容,但能看到你连了哪个域名(SNI) |
| 加密在应用之下 | 数据到了服务端就是明文;服务端被入侵 = 数据泄露,HTTPS 管不了 |
2. 实测:看一条真实连接的证书链
$ openssl s_client -connect clxhxhhr.top:443 -servername clxhxhhr.top -showcerts
实测输出(关键行):
subject=CN = clxhxhhr.top
issuer=C = US, O = Let's Encrypt, CN = YE2
Verification: OK
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Verify return code: 0 (ok)
证书链(实测四层):
0 s:CN = clxhxhhr.top ← 叶证书(服务器自己的)
i:C = US, O = Let's Encrypt, CN = YE2 ← 签发者:Let's Encrypt 中间 CA
1 s:C = US, O = Let's Encrypt, CN = YE2
i:C = US, O = ISRG, CN = Root YE ← 再上一级
2 s:C = US, O = ISRG, CN = Root YE
i:... CN = ISRG Root X2
3 s:CN = ISRG Root X2
i:... CN = ISRG Root X1 ← 根证书(客户端内置信任)
怎么读这条链:验证方向是从叶到根——每一级用上一级的公钥验签,最后一级必须是客户端预置信任的根证书。链条上任何一环缺失或不匹配,就会 certificate verify failed。
3. HTTP 报文结构(30 秒复习)
GET /index.html HTTP/1.1 ← 请求行:方法 + 路径 + 版本
Host: example.com ← 头部(键值对)
Accept: text/html
← 空行(分隔头与体)
[请求体] ← GET 通常无,POST 有
响应:
HTTP/1.1 200 OK ← 状态行:版本 + 状态码 + 原因
Content-Type: text/html
Content-Length: 1234
← 空行
[响应体]
| 状态码区间 | 含义 | 典型 |
|---|---|---|
| 1xx | 信息(继续) | 101 Switching Protocols(WebSocket 用) |
| 2xx | 成功 | 200、201、204 |
| 3xx | 重定向 | 301 永久、302 临时、304 未修改 |
| 4xx | 客户端错 | 400、401、403、404、429 |
| 5xx | 服务端错 | 500、502、503、504 |
一个必须知道的细节:
301会被浏览器长期缓存,改错了很难挽回;调试期用302更安全。
4. TLS 握手:TLS 1.2 与 1.3 差在哪(E-S02-011)
| 项 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| 往返次数 | 2-RTT | 1-RTT(会话复用可 0-RTT) |
| 密钥交换 | 允许 RSA(无前向安全) | 只允许(EC)DHE(强制前向安全) |
| 加密套件 | 一大堆 | 精简到 5 个 |
| 握手明文部分 | 较多 | 只有 ClientHello 明文 |
实测(curl -v)看到的就是 1.3 的 1-RTT 结构:
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
注意 Encrypted Extensions:1.3 里服务器证书是加密传输的(除了 SNI),所以抓包只能看到"连了哪个域名",看不到证书细节——这是与 1.2 的重要区别。
4.1 0-RTT 的代价
会话复用可以让客户端在第一个包里就带数据(0-RTT),但这批数据可能被重放。所以:
判据:0-RTT 只用于幂等请求(GET 查询),不要用于支付/下单。
5. 证书验证:三个必须同时成立的检查(E-S02-012)
| 检查 | 内容 | 失败报错 |
|---|---|---|
| 链可信 | 叶→中间→根,根在信任库 | unable to get local issuer certificate |
| 域名匹配 | 证书 SAN 里包含你访问的域名 | certificate has expired 之外的 does not match |
| 时间有效 | 在 notBefore 与 notAfter 之间 |
certificate has expired |
三个都过才算验证成功。 排障时先分清是哪一类——这决定了你去修链、改域名、还是续期(J02 详讲)。
5.1 SNI:一个 IP 多个网站怎么区分
客户端在 ClientHello 里带 SNI(Server Name Indication),服务器据此选证书。
排障含义:openssl s_client -connect ip:443 不加 -servername,很可能拿到默认证书(不是你要的那个域名),从而误判"证书不对"。加 -servername 是必须的。
6. HTTPS 挡得住什么、挡不住什么
| 攻击/风险 | HTTPS 能挡吗 | 说明 |
|---|---|---|
| 中间人窃听内容 | ✅ | 除非客户端信任了攻击者的根证书 |
| 内容篡改 | ✅ | 完整性校验(AEAD) |
| 冒充服务端 | ✅ | 证书验证 |
| 知道你访问哪个域名 | ❌ | SNI 在 1.3 里仍可能明文(ECH 尚未普及,待核) |
| 流量特征分析 | ❌ | 包大小、时序仍可分析 |
| 服务端数据泄露 | ❌ | 到了服务端就是明文 |
| XSS / SQL 注入 | ❌ | 应用层漏洞 |
| 客户端被装恶意根证书 | ❌ | 企业内部代理就是靠这个"合法"解密 |
一句判据:HTTPS 保护"路上",不保护"两头"。
7. 五个误区
| 误区 | 真相 |
|---|---|
| "用了 HTTPS 网站就安全了" | 只保证传输;应用漏洞照样能被打 |
| "证书越贵越安全" | 加密强度与价格无关;免费 Let's Encrypt 一样是 TLS 1.3 |
| "HTTP/2 必须用 HTTPS" | 浏览器实现如此,协议本身不强制 |
| "抓不到包就说明加密了" | 能看到 SNI 与流量特征 |
| "自签证书加个信任就行" | 生产环境应走公共 CA 或企业 CA 统一分发,自签只用于测试 |
8. 自检
- 加密发生在哪一层?为什么这决定了"服务端仍是明文"?
- 证书链验证的三个检查是什么?各对应什么报错?
- 为什么
openssl s_client必须加-servername? - TLS 1.3 相比 1.2 的两个关键改进是什么?
- 0-RTT 为什么不能用于下单接口?
9. 下一篇
S02-B07 · WebSocket、SSE、长轮询:四种实时通信怎么选
HTTP 是"请求-响应",但很多场景需要"服务端主动推"。下一篇用真实抓到的 SSE 流(带毫秒时间戳)与 WebSocket 握手计算(Sec-WebSocket-Accept),讲清四种机制的差别与选型判据。
本篇属于系列《S02 · 计算机与网络基础》。旧文来源:A-1036、A-488;扩展点 E-S02-011/012。证书链与 TLS 1.3 握手为 2026-11-05 实测。