Computer NetworkNotes

第 15 章:HTTPS 与 TLS

zjc 于 2026-01-15 发布

这是《计算机网络 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 HTTPS 在 HTTP 语义之下加入 TLS,提供身份认证、机密性和完整性保护。生产中 HTTPS 的问题往往集中在证书链、域名匹配、协议版本、SNI、ALPN、证书轮换和会话恢复。本章把这些机制串成可部署、可排障的知识链。

15.1 TLS 解决什么问题

没有加密的 HTTP 面临:

  1. 窃听:路径设备可以看到内容;
  2. 篡改:响应或请求可被修改;
  3. 冒充:攻击者伪装服务端;
  4. 泄露:URL、Header、Cookie 明文传输。

TLS 提供:

能力 机制
认证 证书和信任链
机密性 协商对称密钥加密
完整性 AEAD 或 MAC
前向安全 临时密钥交换
应用协议协商 ALPN

15.2 证书体系

证书链:

Root CA
  -> Intermediate CA
     -> Server Certificate

服务端通常发送服务器证书和中间证书。根证书预置在操作系统或浏览器信任库中,不由服务端发送。

证书包含:

  1. Subject / Issuer;
  2. 有效期;
  3. SAN 域名;
  4. 公钥;
  5. 签名算法;
  6. 密钥用途;
  7. 扩展约束。

校验通过的条件:

  1. 证书链可追溯到受信任 CA;
  2. 当前时间在有效期内;
  3. 域名匹配 SAN;
  4. 用途正确;
  5. 未被吊销或按策略完成吊销检查;
  6. 签名算法和安全策略满足要求。

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. 通常 1 RTT 建连;
  2. 握手后大部分消息加密;
  3. 删除弱算法;
  4. 默认前向安全;
  5. 支持 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 校验服务端证书

流程:

  1. CA 签发客户端证书;
  2. 服务端配置信任 CA 和校验模式;
  3. 客户端发送证书和私钥证明;
  4. 服务端读取证书身份;
  5. 应用映射证书到权限。

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. 记录指纹和有效期

要求:

  1. 到期前至少提前数天告警;
  2. 自动化签发和部署;
  3. 中间证书必须完整;
  4. 私钥权限最小化;
  5. 支持热加载;
  6. 多域名和泛域名统一治理;
  7. 轮换后全链路探测。

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 性能

优化:

  1. 使用 TLS 1.3;
  2. 启用会话恢复;
  3. 配置 OCSP Stapling;
  4. 保留 HTTP/2 长连接;
  5. 使用硬件加速或优化的密码库;
  6. 减少证书链长度;
  7. 就近接入;
  8. 会话票据密钥安全轮换。

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 主要故障来源。

思考题

  1. TLS 1.2 和 TLS 1.3 握手有什么差异?
  2. 为什么服务端必须发送中间证书?
  3. SNI 和 ALPN 分别解决什么问题?
  4. 0-RTT 的重放风险如何缓解?
  5. 写一份生产证书轮换和回滚流程。