【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

为什么 HTTPS 需要 7 次握手以及 9 倍时延?

  • 2020-02-28
  • 本文字数:3237 字

    阅读完需:约 11 分钟

为什么 HTTPS 需要 7 次握手以及 9 倍时延?

为什么这么设计(Why’s THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点、对具体实现造成的影响。如果你有想要了解的问题,可以在文章下面留言。


HTTP 协议(Hypertext Transfer Protocol)已经成为互联网上最常用的应用层协议,然而其本身只是用于传输超文本的网络协议,不会提供任何安全上的保证,使用明文在互联网上传输数据包使得窃听和中间人攻击成为可能,通过 HTTP 传输密码其实与在互联网上裸奔也差不多。



图 1 - HTTPS 协议


网景(Netscape)在 1994 年设计了 HTTPS 协议,使用安全套接字层(Secure Sockets Layer,SSL)保证数据传输的安全1,随着传输层安全协议(Transport Layer Security,TLS)的发展,目前我们已经使用 TLS 取代了废弃的 SSL 协议,不过仍然使用 SSL 证书一词2


HTTPS 是对 HTTP 协议的扩展,我们可以使用它在互联网上安全地传输数据3,然而 HTTPS 请求的发起方第一次从接收方获取响应需要经过 4.5 倍的往返延迟(Round-Trip Time,RTT)。本文将详细介绍请求发起和响应的过程,分析为什么 HTTPS 协议需要通过 4.5-RTT 的时间获得服务提供方的响应:


  • TCP 协议 — 通信双方通过三次握手建立 TCP 连接4

  • TLS 协议 — 通信双方通过四次握手建立 TLS 连接5

  • HTTP 协议 — 客户端向服务端发送请求,服务端发回响应;


这里的分析建立在特定版本的协议实现以及常见场景上,随着网络技术的发展,我们能够减少需要的网络通信次数,本文会在对应章节中提到一些常见的优化方案。

TCP

HTTP 协议作为应用层协议,它需要底层的传输层协议为其提供基本的数据传输功能,HTTP 协议一般都会使用 TCP 协议作为底层协议。为了阻止错误的建立历史连接,TCP 协议通信的双方会通过三次握手建立 TCP 连接6,我们在这里简单回顾一下 TCP 连接建立的整个过程。



图 2 - TCP 三次握手


  1. 客户端向服务端发送带有 SYN 的数据段以及客户端开始发送数据段(Segment)的初始序列号 SEQ = 100

  2. 服务端收到数据段时,向客户端发送带有 SYNACK 的数据段;

  3. 通过返回 ACK = 101 确认客户端数据段的初始序列号;

  4. 通过发送 SEQ = 300 通知客户端,服务端开始发送数据段的初始序列号;

  5. 客户端向服务端发送带有 ACK 的数据段,确认服务端的初始序列号,其中包含 ACK = 301


TCP 连接的双方会通过三次握手确定 TCP 连接的初始序列号、窗口大小以及最大数据段,这样通信双方就能利用连接中的初始序列号保证双方数据段的不重不漏、通过窗口大小控制流量并使用最大数据段避免 IP 协议对数据包的分片7


最初版本的 TCP 协议确实会通过三次通信建立 TCP 连接,在目前的大多数场景下,三次握手也是无法避免的,不过在 2014 年提出的 TCP 快启(TCP Fast Open,TFO)却可以在某些场景下通过一次通信建立 TCP 连接8



图 3 - TCP 快启


TCP 快启策略使用存储在客户端的 TFO Cookie 与服务端快速建立连接。TCP 连接的客户端向服务端发送 SYN 消息时会携带快启选项,服务端会生成一个 Cookie 并将其发送至客户端,客户端会缓存该 Cookie,当其与服务端重新建立连接时,它会使用存储的 Cookie 直接建立 TCP 连接,服务端验证 Cookie 后会向客户端发送 SYNACK 并开始传输数据,这也就能减少通信的次数。

TLS

TLS 的作用是在可靠的 TCP 协议上构建安全的传输通道,其本身是不提供可靠性保障的,我们还是需要下层可靠的传输层协议。在通信双方建立可靠的 TCP 连接之后,我们就需要通过 TLS 握手交换双方的密钥了,在这里我们将介绍 TLS 1.2 的连接建立过程9



图 4 - TLS 1.2 建立连接


  1. 客户端向服务端发送 Client Hello 消息,其中携带客户端支持的协议版本、加密算法、压缩算法以及客户端生成的随机数

  2. 服务端收到客户端支持的协议版本、加密算法等信息后;

  3. 向客户端发送 Server Hello 消息,并携带选择特定的协议版本、加密方法、会话 ID 以及服务端生成的随机数

  4. 向客户端发送 Certificate 消息,即服务端的证书链,其中包含证书支持的域名、发行方和有效期等信息;

  5. 向客户端发送 Server Key Exchange 消息,传递公钥以及签名等信息;

  6. 向客户端发送可选的消息 CertificateRequest,验证客户端的证书;

  7. 向客户端发送 Server Hello Done 消息,通知服务端已经发送了全部的相关信息;

  8. 客户端收到服务端的协议版本、加密方法、会话 ID 以及证书等信息后,验证服务端的证书;

  9. 向服务端发送 Client Key Exchange 消息,包含使用服务端公钥加密后的随机字符串,即预主密钥(Pre Master Secret);

  10. 向服务端发送 Change Cipher Spec 消息,通知服务端后面的数据段会加密传输;

  11. 向服务端发送 Finished 消息,其中包含加密后的握手信息;

  12. 服务端收到 Change Cipher Spec 和 Finished 消息后;

  13. 向客户端发送 Change Cipher Spec 消息,通知客户端后面的数据段会加密传输;

  14. 向客户端发送 Finished 消息,验证客户端的 Finished 消息并完成 TLS 握手;


TLS 握手的关键在于利用通信双方生成的随机字符串和服务端的公钥生成一个双方经过协商后的密钥,通信的双方可以使用这个对称的密钥加密消息防止中间人的监听和攻击,保证通信的安全。


在 TLS 1.2 中,我们需要 2-RTT 才能建立 TLS 连接10,但是 TLS 1.3 通过优化协议,将两次往返延迟降低至一次,大幅度减少建立 TLS 连接所需要的时间,让客户端可以在 1-RTT 之后就能向服务端传输应用层数据。


这里就不展开介绍 TLS 1.3 建立连接的过程了,除了减少常规握手下的网络开销,TLS 1.3 还引入了 0-RTT 的连接建立过程;60% 的网络连接都是用户在第一次访问网站或者间隔一段时间后访问时建立的,剩下的 40% 可以通过 TLS 1.3 的 0-RTT 策略解决11,然而该策略与 TFO 的实现原理比较相似,都是通过重用会话和缓存来实现的,所以存在一定的安全风险,使用时也应该结合业务的具体场景。

HTTP

在已经建立好 TCP 和 TLS 通道上传输数据是比较简单的事情,HTTP 协议可以直接利用下层建立的可靠的、安全的通道传输数据。客户端通过 TCP 的套接字接口向服务端写入数据,服务端在接收到数据、进行处理后通过相同的途径返回。因为整个过程需要客户端发送请求以及服务端返回响应,所以耗时是 1-RTT。



图 5 - HTTP 请求和响应


HTTP 协议的数据交换只会消耗 1-RTT,当客户端和服务端仅处理一次 HTTP 请求时,从 HTTP 协议本身我们已经无法进行优化。不过随着请求的数量逐渐增加,HTTP/2 就可以复用已经建立的 TCP 连接减少 TCP 和 TLS 握手带来的额外开销。

总结

当客户端想要通过 HTTPS 请求访问服务端时,整个过程需要经过 7 次握手并消耗 9 倍的延迟。如果客户端和服务端因为物理距离上的限制,RTT 约为 40ms 时,第一次请求需要 ~180ms;不过如果我们想要访问美国的服务器,RTT 约为 200ms 时,这时 HTTPS 请求的耗时为 ~900ms,这就是一个比较高的耗时了。我们来总结一下 HTTPS 协议需要 9 倍时延才能完成通信的原因:


  1. TCP 协议需要通过三次握手建立 TCP 连接保证通信的可靠性(1.5-RTT);

  2. TLS 协议会在 TCP 协议之上通过四次握手建立 TLS 连接保证通信的安全性(2-RTT);

  3. HTTP 协议会在 TCP 和 TLS 上通过一次往返发送请求并接收响应(1-RTT);


需要注意的是,本文对往返延时的计算都基于特定的场景以及特定的协议版本,网络协议的版本在不断更新和演进,过去忽略的问题最开始都会通过补丁的方式更新,但是最后仍然会需要从底层完成重写。


HTTP/3 就是一个这样的例子,它会使用基于 UDP 的 QUIC 协议进行握手,将 TCP 和 TLS 的握手过程结合起来,把 7 次握手减少到了 3 次握手,直接建立了可靠并且安全的传输通道,将原本 ~900ms 的耗时降低至 ~500ms,我们会在后面的文章介绍 HTTP/3 协议相关的内容。到最后,我们还是来看一些比较开放的相关问题,有兴趣的读者可以仔细思考一下下面的问题:


  • 作为传输层协议,QUIC 协议和 TCP 协议之间有什么异同?

  • 为什么可以通过 0-RTT 建立客户端和服务端的连接?


本文转载自 Draveness 技术网站。


原文链接:https://draveness.me/whys-the-design-https-latency


2020-02-28 17:24888

评论

发布
暂无评论
发现更多内容

“他”靠这份GitHub star过万的1121页图解算法成功杀进字节跳动

Java 编程 程序员 IT 计算机

汽车的新能源之变,不仅在一块电池

脑极体

拒绝焦虑!Alibaba巨擎随手甩来的一本Java性能优化让我收获满满

Java 架构 面试 程序人生 编程语言

自定义View:文字的测量与绘制

Changing Lin

10月月更

动态模型之增压暂停【FunTester测试框架】

FunTester

性能测试 接口测试 测试框架 FunTester 动态模型

Python代码阅读(第36篇):列表偏移

Felix

Python 编程 Code Programing 阅读代码

Linux服务器部署服务

黄敏

【浪潮云说】直播间第九期今晚20:00准时开播

浪潮云

云计算

音视频编解码 -- 编码参数 CRF

声网

ffmpeg 视频编解码 视频压缩 CRF

Linux渗透:曲折渗透之路

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

同事跳槽阿里,临走甩给一份上千页的Linux源码笔记,真香

Java 程序员 架构 面试 后端

【直播回顾】5步实现精细化用户触达,助力业务增长

极光JIGUANG

消息推送 用户触达

秋招如何抱佛脚?2021最新大厂Java面试真题合集(附权威答案)

Java 编程 程序员 架构 IT

30天肝出来的Java面试手册!登顶Github标星288k

Java 程序员 架构 面试 后端

递推算法与递推套路(算法基础篇)

有道技术团队

算法 大前端 网易有道

J2PaaS 低代码平台,正式发布开源版!

J2PaaS低代码平台

低代码 零代码 低代码开发 低代码开发平台 无代码平台

2.两数相加(链表)

黄敏

2021云栖大会丨果断收藏!「混合云参会指南」来啦~

人工智能 阿里云 互联网 云栖大会 前沿科技

阿里巨擎耗时六个月整理的这套图解HTTP笔记,在Github上被疯狂转载!

Java 架构 面试 程序人生 编程语言

Angular 依赖注入 - 全面解析

PingCode研发中心

angular 依赖注入 对象提供者 注入器 令牌

EDA 事件驱动架构与 EventBridge 二三事

阿里巴巴云原生

阿里云 云原生 EDA架构 事件驱动型架构

Spring Boot 这样的优化,让你的项目飞起来

程序员小呆

Java 程序员 架构师

EMQ X VS RabbitMQ:两大消息服务器 MQTT 性能对比全解(下)

EMQ映云科技

RabbitMQ 物联网 IoT mqtt emq

吹爆!阿里高工携18位架构师耗时57天整合的1658页面试总结太香了

Java 编程 程序员 架构 面试

智能化如何升级传统厨房烹饪体验?苏泊尔与鸿蒙智联携手交出创新答卷

科技汇

绝了!Java程序员面试全方位贴身指南,轻松跳槽获取高薪资offer

程序员 架构 面试 后端 java

真香!肝完Alibaba这份面试通关宝典,我成功拿下今年第15个Offer

Java 编程 程序员 IT 计算机

好家伙!华为内部Java系统优化笔记一夜之间跃居Github热榜第二

Java 架构 IT 计算机 知识分享

限时开源!阿里内部爆款的顶配版Spring Security笔记

Java spring 编程 架构 面试

Java通过socket和DTU,RTU连接工业传感器通信

叫练

socket Modbus协议 java DTU RTU

网易云信 NERTC 高清画质体验之 H.265的工程实践 | 体验共享技术专题

网易云信

Java 测试 音视频 视频

为什么 HTTPS 需要 7 次握手以及 9 倍时延?_文化 & 方法_Draveness_InfoQ精选文章