--- tags: [计算机网络, HTTPS, TLS, 证书, PKI] create time: 2026-05-18 03:00 --- # HTTPS 与 TLS 握手 ## 概述 HTTPS = HTTP over TLS(Transport Layer Security)。TLS 在 TCP 和应用层之间插入一个加密通道,确保通信的机密性、完整性和对端身份验证。理解 TLS 握手过程是排查 SSL 错误的核心能力。 ## TLS 在协议栈中的位置 ``` ┌─────────────┐ │ HTTP │ ← 应用层 ├─────────────┤ │ TLS │ ← "加密壳" — 透明包装下层数据 ├─────────────┤ │ TCP │ ← 可靠传输 ├─────────────┤ │ IP │ ← 路由 └─────────────┘ ``` ## TLS 握手流程(TLS 1.3) ### 完整交互序列 ```mermaid sequenceDiagram participant C as Client participant S as Server Note over C,S: Phase 1: Key Exchange (Full Handshake) C->>S: ClientHello
• TLS version (1.3)
• Cipher suites (pref order)
• Random bytes
• PSK/session ticket (optional)
• Extensions (ALPN, SNI...) S-->>C: ServerHello
• Selected cipher suite
• Random bytes
• Server's key share (ephemeral ECDHE) S->>S: Send certificate + cert_chain S->>C: CertificateRequest (optional) S->>C: ServerKeyExchange (if needed) S->>C: ServerFinished C->>C: Verify cert chain → CA ✓ C->>S: ClientKeyExchange (key share) C->>C: Compute shared secret (ECDHE) C->>S: ChangeCipherSpec (implicit in 1.3) C->>S: ClientFinished Note over C,S: ← Encryption Enabled ✨ --> C->>S: Application data (HTTP Request) 🔒 S->>C: Application data (HTTP Response) 🔒 ``` ### TLS 1.3 vs TLS 1.2 对比 | 特性 | TLS 1.2 | TLS 1.3 | |------|---------|---------| | **往返次数** | 2 RTT (或 1 RTT with session resumption) | **1 RTT** (0 RTT if resumed) ⚡ | | 密钥交换 | RSA / DHE / ECDHE | **仅 ECDHE** (前向安全强制) | | Cipher Suites | ~30+ 种选择 | **仅 4 种** (AES-GCM, ChaCha20-Poly1305) | | 压缩 | ✅ (导致 CRIME 漏洞) | ❌ **已禁用** | | 重协商 | ✅ | ❌ (改用 NewSession Ticket) | | 静态 RSA 密钥交换 | ✅ | ❌ **已移除** | | CBC 模式密文 | ✅ | ❌ **已移除** | | Export ciphers | ✅ | ❌ **已移除** | | Renegotiation | ✅ | ❌ (用 renegotiation_info 扩展替代) | > [!tip] TLS 1.3 为什么更快? > TLS 1.2: ClientHello → ServerHello → Certificate → ServerKeyExchange → ... → ClientKeyExchange → Finished = **2 full RTTs** > > TLS 1.3: ClientHello (含 client key share) → ServerHello (含 server key share) + Certificate + Finished = **1 RTT** > > 因为客户端在第一个包中就携带了自己的密钥共享信息,无需等待服务器回复后再计算。 ## Cipher Suite 详解 TLS 1.3 只有 4 个 Cipher Suites: | 编号 | Cipher Suite | KEM | AEAD | HKDF | |------|-------------|-----|------|------| | TLS_AES_128_GCM_SHA256 | AES-128-GCM | X25519 | AES-128-GCM | SHA256 | | TLS_AES_256_GCM_SHA384 | AES-256-GCM | X25519 | AES-256-GCM | SHA384 | | TLS_CHACHA20_POLY1305_SHA256 | ChaCha20-Poly1305 | X25519 | ChaCha20-Poly1305 | SHA256 | | TLS_AES_128_CCM_SHA256 | AES-128-CCM | X25519 | AES-128-CCM | SHA256 | **Go 中默认偏好顺序:** `TLS_AES_256_GCM_SHA384 > TLS_AES_128_GCM_SHA256 > TLS_CHACHA20_POLY1305_SHA256` ## 证书链验证流程 ```mermaid flowchart TD Cert["Server Certificate
CN = example.com"] -->|"issued by"| Inter["Intermediate CA
ISRG Root X1"] Inter -->|"issued by"| Root["Root CA
DigiCert Global Root G2"] Root -->|"self-signed"| Root Client["Client 浏览器"] -->|"验证:"| V1["1. 签名是否由上层CA签发?"] V1 -->|"是"| V2["2. CN/SAN 是否匹配域名?"] V2 -->|"是"| V3["3. 是否过期?"] V3 -->|"是"| V4["4. 是否在 OCSP/CRL 吊销列表中?"] V4 -->|"是"| V5["5. 根证书是否在信任库中?"] V5 -->|"是"| TRUSTED["✅ 信任!"] style TRUSTED fill:#98FB98,color:#000 ``` ## 实际调试命令 ```bash # 查看服务器支持的 TLS 版本和 Cipher Suites $ openssl s_client -connect example.com:443 -tls1_3 CONNECTED(00000003) Protocol : TLSv1.3 Cipher : TLS_AES_256_GCM_SHA384 Certificate chain: 0 s:CN = example.com i:C = US, O = DigiCert Inc, CN = DigiCert TLS Hybrid ECC_SHA384 2020 CA1 # 指定特定 Cipher 测试 $ openssl s_client -connect example.com:443 \ -cipher 'ECDHE-ECDSA-AES256-GCM-SHA384' # 获取证书信息 $ openssl x509 -in cert.pem -noout -dates -subject -issuer subject=CN = example.com notBefore=Jan 1 00:00:00 2025 GMT notAfter=Jan 1 00:00:00 2026 GMT # 检查 OCSP 状态 $ curl -vI https://example.com < HTTP/2 200 < alt-s: h3=":443"; ma=86400 < alt-s: h2=":443"; ma=86400 # Go 中自定义证书验证 import "crypto/tls" config := &tls.Config{ InsecureSkipVerify: false, // 生产环境永远为 false MinVersion: tls.VersionTLS13, } conn, _ := tls.Dial("tcp", "example.com:443", config) ``` ## Go 标准库中的 TLS ```go // 创建安全的 TLS 配置 var DefaultTLSConfig = tls.Config{ MinVersion: tls.VersionTLS12, // 最低支持 TLS 1.2 PreferServerCipherSuites: true, } // http.Server 自动启用 TLS srv := &http.Server{ Addr: ":443", Handler: handler, TLSConfig: &tls.Config{ MinVersion: tls.VersionTLS13, NextProtos: []string{"h2", "http/1.1"}, // ALPN }, } srv.ListenAndServeTLS("cert.pem", "key.pem") // 或 Let's Encrypt (auto TLS) import "crypto/tls" mux.HandleFunc("/", handler) go http.ListenAndServe(":80", nil) // ACME Challenge go http.ListenAndServeTLS(":443", "", "", &http.Server{ Handler: mux, TLSConfig: &tls.Config{ GetCertificate: autoTLSManager.GetCertificate, NextProtos: []string{"h2", "http/1.1"}, }, }) ``` ## 关联笔记 - [[hhs/NETWORK/HTTP/3与QUIC]] — QUIC 内置 TLS 1.3 - [[hhs/NETWORK/DNS原理与优化]] — SNI 扩展帮助 DNS 和 CDN 调度 - [[hhs/NETWORK/SSL Strip-Heartbleed]] — TLS 历史安全漏洞