这是《计算机网络 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 HTTPS 在 HTTP 语义之下加入 TLS,提供身份认证、机密性和完整性保护。生产中 HTTPS 的问题往往集中在证书链、域名匹配、协议版本、SNI、ALPN、证书轮换和会话恢复。本章把这些机制串成可部署、可排障的知识链。
15.1 TLS 解决什么问题
没有加密的 HTTP 面临:
- 窃听:路径设备可以看到内容;
- 篡改:响应或请求可被修改;
- 冒充:攻击者伪装服务端;
- 泄露:URL、Header、Cookie 明文传输。
TLS 提供:
| 能力 | 机制 |
|---|---|
| 认证 | 证书和信任链 |
| 机密性 | 协商对称密钥加密 |
| 完整性 | AEAD 或 MAC |
| 前向安全 | 临时密钥交换 |
| 应用协议协商 | ALPN |
15.2 证书体系
证书链:
Root CA
-> Intermediate CA
-> Server Certificate
服务端通常发送服务器证书和中间证书。根证书预置在操作系统或浏览器信任库中,不由服务端发送。
证书包含:
- Subject / Issuer;
- 有效期;
- SAN 域名;
- 公钥;
- 签名算法;
- 密钥用途;
- 扩展约束。
校验通过的条件:
- 证书链可追溯到受信任 CA;
- 当前时间在有效期内;
- 域名匹配 SAN;
- 用途正确;
- 未被吊销或按策略完成吊销检查;
- 签名算法和安全策略满足要求。
15.3 TLS 1.2 握手
简化流程:
Client
-> ClientHello:支持的套件、随机数、SNI、扩展
Server
-> ServerHello:选择套件、随机数
-> Certificate
-> ServerKeyExchange
-> ServerHelloDone
Client
-> ClientKeyExchange
-> ChangeCipherSpec
-> Finished
Server
-> ChangeCipherSpec
-> Finished
TLS 1.2 建连通常需要 2 RTT,再叠加 TCP 握手 1 RTT。
15.4 TLS 1.3 握手
简化流程:
Client
-> ClientHello:key_share、SNI、ALPN
Server
-> ServerHello
-> EncryptedExtensions
-> Certificate
-> CertificateVerify
-> Finished
Client
-> Finished
特点:
- 通常 1 RTT 建连;
- 握手后大部分消息加密;
- 删除弱算法;
- 默认前向安全;
- 支持 0-RTT 恢复。
0-RTT 降低延迟,但重放风险需要应用层防护,不适合非幂等请求直接使用。
15.5 SNI 与 ALPN
SNI
一个 IP 上承载多个 HTTPS 域名时,客户端在 ClientHello 中发送目标域名,服务器据此选择证书:
SNI: www.example.com
TLS 1.3 中 ClientHello 仍明文,传统 SNI 域名可能被观察。Encrypted Client Hello 是后续增强,部署依赖客户端和服务端支持。
ALPN
ALPN 协商应用协议:
Client:h2, http/1.1
Server:h2
没有 ALPN 时,通常退回 HTTP/1.1。
15.6 会话恢复
方式:
| 机制 | 特点 |
|---|---|
| Session ID | 服务端保存会话状态 |
| Session Ticket | 服务端加密状态交给客户端保存 |
| TLS 1.3 PSK | 支持恢复和 0-RTT |
会话恢复减少握手 RTT,但密钥轮换和票据管理要安全治理。
15.7 mTLS
双向 TLS 要求客户端也提供证书:
Server 校验客户端证书
Client 校验服务端证书
流程:
- CA 签发客户端证书;
- 服务端配置信任 CA 和校验模式;
- 客户端发送证书和私钥证明;
- 服务端读取证书身份;
- 应用映射证书到权限。
Nginx 示例:
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/nginx/tls/server.crt;
ssl_certificate_key /etc/nginx/tls/server.key;
ssl_client_certificate /etc/nginx/tls/client-ca.crt;
ssl_verify_client on;
}
注意:证书只证明身份,不代表授权,仍需授权系统。
15.8 证书轮换
流程:
1. 监控证书到期时间
2. 签发新证书
3. 在测试环境验证证书链
4. 更新 LB / Ingress / 服务
5. 滚动重启或热加载
6. 验证客户端兼容
7. 保留旧证书回滚窗口
8. 记录指纹和有效期
要求:
- 到期前至少提前数天告警;
- 自动化签发和部署;
- 中间证书必须完整;
- 私钥权限最小化;
- 支持热加载;
- 多域名和泛域名统一治理;
- 轮换后全链路探测。
15.9 排查命令
查看证书:
openssl s_client -connect www.example.com:443 -servername www.example.com
openssl x509 -in server.crt -noout -text
openssl x509 -in server.crt -noout -dates -subject -issuer
测试协议:
openssl s_client -connect www.example.com:443 -tls1_2
openssl s_client -connect www.example.com:443 -tls1_3
curl -v --http2 https://www.example.com
常见错误:
| 报错 | 原因 |
|---|---|
| certificate has expired | 证书过期 |
| unable to get local issuer certificate | 缺中间证书或信任库缺失 |
| hostname mismatch | SAN 不匹配 |
| certificate signed by unknown authority | 自签或私有 CA 未信任 |
| protocol version | 协议不兼容 |
| handshake failure | 套件、SNI、策略不匹配 |
15.10 HTTPS 性能
优化:
- 使用 TLS 1.3;
- 启用会话恢复;
- 配置 OCSP Stapling;
- 保留 HTTP/2 长连接;
- 使用硬件加速或优化的密码库;
- 减少证书链长度;
- 就近接入;
- 会话票据密钥安全轮换。
Nginx 示例:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
安全与性能需要平衡。禁用 TLS 1.2 前要确认客户端支持。
本章小结
HTTPS 通过证书链认证服务端身份,通过密钥协商建立加密通道,TLS 1.3 将握手降为 1 RTT 并增强前向安全。SNI 支持单 IP 多域名,ALPN 协商 HTTP/2 和 HTTP/3,mTLS 可用于服务间认证。证书链不完整、过期、SAN 不匹配、SNI 错误和协议不兼容是 HTTPS 主要故障来源。
思考题
- TLS 1.2 和 TLS 1.3 握手有什么差异?
- 为什么服务端必须发送中间证书?
- SNI 和 ALPN 分别解决什么问题?
- 0-RTT 的重放风险如何缓解?
- 写一份生产证书轮换和回滚流程。