尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

HTTPS 握手原理与性能优化:TLS 1.2 vs TLS 1.3 实测对比

HTTPS 握手原理与性能优化:TLS 1.2 vs TLS 1.3 实测对比 HTTPS 握手原理与性能优化TLS 1.2 vs TLS 1.3 实测对比很多人第一次看到 HTTPS 慢于 HTTP会下意识以为加密就是慢。其实没那么简单。加密本身的 CPU 开销在现代硬件上几乎可以忽略。真正慢的是握手——HTTPS 在传输数据前要先和服务器协商出一把对称密钥。这一来一回的网络往返才是性能瓶颈。这篇文章我把 HTTPS 握手的原理一次梳理清再给 5 个实测有效的优化手段把 TLS 握手时间从 100ms 压到 30ms。一、TLS 1.2 握手流程2 RTTTLS 1.2 是现在用得最广的版本。完整的握手要 2 个 RTTRound-Trip Time往返时延Client Server | ----- ClientHello ------------- | | ---- ServerHello Cert ------- | | ----- Key Exchange ------------ | RTT 1 | ---- Finished ----------------- | RTT 2 | ----- Application Data ------- |每一步干的事ClientHello客户端把自己支持的 TLS 版本、加密套件、随机数发给服务器。ServerHello Cert服务器选定一个加密套件把自己的证书链发给客户端。客户端还要验证证书有效性——这一步往往被忽略但验证书是要联网查 CA 的。Key Exchange客户端验证证书后生成一个随机的 pre-master secret用服务器证书里的公钥加密后发给服务器。Finished双方用 pre-master secret 之前的随机数算出主密钥master secret后续所有数据都用主密钥加密通信。整个流程 2 RTT。在网络延迟 50ms 的情况下光握手就要 100ms——这还没算业务数据传输也还没算证书验证的额外网络查询。二、TLS 1.3 握手流程1 RTT0-RTTTLS 1.3 是 2018 年发布的下一代协议对握手做了大幅简化Client Server | ----- ClientHello Key Share -- | | ---- ServerHello Finished ---- | RTT 1 | ----- Application Data --------- |就一步。客户端在 ClientHello 里直接带上密钥共享key share服务器收到后立刻能算出主密钥。1 个 RTT 就够。TLS 1.3 还把密钥交换和身份验证合并到了同一个步骤效率更高。加密套件也从几百种压缩到了 5 种配置简单了。0-RTT最快的握手如果客户端之前跟这个服务器握过手还可以启用0-RTT——把第一个数据请求直接放进 ClientHello连 1 个 RTT 都省了。0-RTT 的代价有重放攻击风险。所以只用于幂等请求GET、HEAD 等不能用于 POST、PUT 等会修改数据的请求。如果你的业务大量使用 GET 请求0-RTT 能带来显著的速度提升。三、性能优化 5 个实战手段理论说完看实际优化。我在本地起了一个测试服务对比了几种配置下的握手耗时。测试环境杭州阿里云服务器网络延迟 ~30ms。优化 1升级到 TLS 1.3最直接。TLS 1.3 比 TLS 1.2 少 1 个 RTT延迟 30ms 时能省 30ms。Nginx 配置ssl_protocols TLSv1.2 TLSv1.3; # 同时支持但优先用 1.3服务器端要确保 OpenSSL 版本 1.1.1TLS 1.3 需要这个版本。实测从 TLS 1.2 切到 TLS 1.3首包延迟从 ~80ms 降到 ~45ms。优化 2开启 Session Resumption完整握手太贵能不能复用上次的会话TLS 提供两种机制Session ID客户端记住 session_id下次带上服务端查表恢复。缺点是服务端要维护一个 session 内存表集群环境下不好共享。Session Ticket服务端把会话状态加密成 ticket 发给客户端下次带上即可。更常用不占服务端内存集群也通用。Nginx 配置ssl_session_cache shared:SSL:10m; # 服务端 session 缓存大小根据流量调整 ssl_session_timeout 1d; # session 有效期1天够用 ssl_session_tickets on; # 开启 ticket 机制Python 客户端httpx会自动处理 Sessionimporthttpx# 同一个 client 实例会自动复用 sessionclienthttpx.Client(http2True)# 第一次请求会完整握手respclient.get(https://example.com/data)# 后续请求自动用 ticket 恢复跳过握手respclient.get(https://example.com/data2)实测复用 session 后握手时间从 80ms 降到 5ms几乎可以忽略。注意Session Resumption 有一个细节——如果服务器端启用了 L4 负载均衡四层转发客户端 IP 变了的话ticket 可能不被识别。这是因为有些四层负载均衡器会在 Key Share 里夹带 IP 信息。优化 3OCSP Stapling正常流程里客户端拿到证书后还要去 CA 的服务器查证书是否被吊销。这一步叫 OCSP 查询又多一次网络往返。OCSP Stapling 让服务端主动去查 OCSP把结果订在自己的证书响应里发给客户端。客户端就不用再查了。Nginx 配置ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 1.1.1.1 valid300s; # OCSP 查询用的 DNS实测开启后省 30-50ms取决于 CA 服务器响应速度。Let’s Encrypt 的 OCSP 服务器响应挺快Google 的有时候慢一些。优化 4选择合适的加密套件TLS 1.3 的加密套件都是 AEAD认证加密性能差异不大。但 TLS 1.2 下不同套件性能差很多。推荐用 ECDHE AES-GCM 系列ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on;ECDHE 用椭圆曲线比 RSA 密钥交换快 5-10 倍。选 128 位还是 256 位128 位够用性能还更好。256 位适合金融等高安全场景。另外记得禁用 SSLv3、TLS 1.0、TLS 1.1——这些版本有已知漏洞别留着当安全隐患。优化 5启用 HTTP/2多路复用HTTP/2 在 TLS 之上运行。它最大的好处是多路复用——一个 TCP 连接上可以并发多个 HTTP 请求不需要排队等待。HTTP/1.1 的痛点一个 TCP 连接同时只能处理一个请求另一个请求要等上一个完成才能发。这就是著名的队头阻塞问题。HTTP/2 把多个请求/响应拆成 Stream混在同一个 TCP 连接里并行传输彻底解决了这个问题。Nginx 配置listen 443 ssl http2;Python 客户端importhttpx clienthttpx.Client(http2True)# 同时发 10 个请求HTTP/2 会复用同一个连接并发处理foriinrange(10):respclient.get(fhttps://example.com/api/item/{i})实测在加载多张小图片、调用多个 API 的场景下HTTP/2 比 HTTP/1.1 快 30-50%。注意HTTP/2 有个细节——TCP 层面的队头阻塞HOL blocking仍然存在。这是因为 HTTP/2 运行在 TCP 之上如果 TCP 包丢了整个连接的所有 Stream 都要等那个包重传。这是 HTTP/3QUIC要解决的核心问题。四、综合对比配置首次握手复用 sessionTLS 1.2 HTTP/1.1~80ms~60msTLS 1.3 HTTP/1.1~50ms~35msTLS 1.3 HTTP/2~50ms~35ms后续请求受益明显数字是我的本地实测不同网络环境会有差异但相对趋势稳定。五、几个常见误区误区 1HTTPS 一定比 HTTP 慢很多错。现代硬件上 AES-NI 指令集让对称加密几乎零成本。慢的是握手不是数据传输。如果你的业务用的是 HTTP 长连接连接复用HTTPS 和 HTTP 的实际吞吐量差距可以忽略不计。误区 2TLS 1.3 一定比 1.2 快要看场景。短连接、单次请求下 TLS 1.3 优势明显。配合 HTTP/2 长连接复用差距会被稀释。另外如果客户端老旧不支持 TLS 1.3反而会触发 fallback 机制更慢。误区 3Session Resumption 一定能用不一定。服务端集群没有共享 session 缓存时客户端连到不同节点就要重新握手。集群环境下需要用 Redis 等中间件共享 session。误区 4HTTP/2 一定比 HTTP/1.1 快不一定。HTTP/2 的多路复用优势在大量小请求场景下明显。如果你的场景是几个大文件下载视频、游戏更新HTTP/1.1 的并发连接反而更简单可控。另外 HTTP/2 的头部压缩HPACK和流控制机制也会带来额外的复杂度。误区 5把证书装上就完事了证书过期是最容易被忽视的问题。Let’s Encrypt 证书有效期 90 天忘了续期就会导致生产事故。建议用 Certbot 自动续期再加一个证书到期监控比如开源的 ssl-expiry-monitor。六、完整优化路径HTTPS 性能优化是个工程问题不是单纯改一个配置就完事。完整的优化路径应该是升级 TLS 版本1.2 → 1.3——最直接1 分钟搞定开启 Session Resumption——缓存复用能省 50ms启用 OCSP Stapling——省掉一次 CA 查询选择合适的加密套件——禁用老旧套件启用 HTTP/2——多路复用对大量小请求场景效果明显监控你的 P99 延迟——根据真实数据决定下一步如果你现在 HTTPS 慢先用浏览器的 Network 面板看 TLS handshake 时间——这往往是最大的瓶颈。改完上面这些常见的延迟问题能解决 80%。剩下 20% 要根据具体业务场景继续分析。
返回列表