(给数据分析与开发加星标,提升数据技能)

来源:真没什么逻辑

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

https-banner

图 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 连接建立的整个过程。

tcp-3-way-handshake

图 2 - TCP 三次握手

  1. 客户端向服务端发送带有 SYN 的数据段以及客户端开始发送数据段(Segment)的初始序列号 SEQ = 100
  2. 服务端收到数据段时,向客户端发送带有 SYN 和 ACK 的数据段;
    1. 通过返回 ACK = 101 确认客户端数据段的初始序列号;
    2. 通过发送 SEQ = 300 通知客户端,服务端开始发送数据段的初始序列号;
  3. 客户端向服务端发送带有 ACK 的数据段,确认服务端的初始序列号,其中包含 ACK = 301

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

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

tcp-fast-open

图 3 - TCP 快启

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

TLS

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

tls-1-2-handshake

图 4 - TLS 1.2 建立连接

  1. 客户端向服务端发送 Client Hello 消息,其中携带客户端支持的协议版本、加密算法、压缩算法以及客户端生成的随机数
  2. 服务端收到客户端支持的协议版本、加密算法等信息后;
    1. 向客户端发送 Server Hello 消息,并携带选择特定的协议版本、加密方法、会话 ID 以及服务端生成的随机数
    2. 向客户端发送 Certificate 消息,即服务端的证书链,其中包含证书支持的域名、发行方和有效期等信息;
    3. 向客户端发送 Server Key Exchange 消息,传递公钥以及签名等信息;
    4. 向客户端发送可选的消息 CertificateRequest,验证客户端的证书;
    5. 向客户端发送 Server Hello Done 消息,通知服务端已经发送了全部的相关信息;
  3. 客户端收到服务端的协议版本、加密方法、会话 ID 以及证书等信息后,验证服务端的证书;
    1. 向服务端发送 Client Key Exchange 消息,包含使用服务端公钥加密后的随机字符串,即预主密钥(Pre Master Secret);
    2. 向服务端发送 Change Cipher Spec 消息,通知服务端后面的数据段会加密传输;
    3. 向服务端发送 Finished 消息,其中包含加密后的握手信息;
  4. 服务端收到 Change Cipher Spec 和 Finished 消息后;
    1. 向客户端发送 Change Cipher Spec 消息,通知客户端后面的数据段会加密传输;
    2. 向客户端发送 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。

http-request-and-response

图 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 建立客户端和服务端的连接?

推荐阅读  点击标题可跳转你连HTTPS 原理都不懂,还讲“中间人攻击”?盘点开发中那些常用的 MySQL 优化哈工大/哈工程被禁用 MATLAB,网友:被卡脖子的领域还不少

看完本文有收获?请转发分享给更多人

关注「数据分析与开发」加星标,提升数据技能

好文章,我在看❤️

curlopt_ssl_verifypeer后https还是验证不过_为什么 HTTPS 需要 7 次握手和 9 倍时延相关推荐

  1. curlopt_ssl_verifypeer后https还是验证不过_为什么 HTTPS 需要 7 次握手和 9 倍时延

    点击上方"五分钟学算法",选择"星标"公众号 重磅干货,第一时间送达 转自真没什么逻辑 HTTP 协议(Hypertext Transfer Protocol) ...

  2. https无法访问 宝塔_宝塔https访问未开启SSL站点跳转到已经开启SSL站点

    在使用宝塔建设多个网站时,如果建两个网站A开启SSL证书,网站B未开启SSL证书当用https访问网站B的时候会强制跳转到网站A.虽然网站B没有开始https,但是搜索引擎会收录https开头的网站B ...

  3. HTTPS 的 7 次握手以及 9 倍时延

    HTTP 协议(Hypertext Transfer Protocol)已经成为互联网上最常用的应用层协议,然而其本身只是用于传输超文本的网络协议,不会提供任何安全上的保证,使用明文在互联网上传输数据 ...

  4. curlopt_ssl_verifypeer后https还是验证不过_验证码识别竞赛解决方案(97%+一等奖)

    前言:这个库是为验证码识别竞赛而开发的一个基于pytorch实现的端到端的验证码识别系统.前后开发大概有2个月,其中大部分时间都在调参,后期参考kaggle大神经验,加入了一些trick,但是由于第一 ...

  5. java证书验证失败_解决https证书验证不通过的问题

    1.报错信息 java.security.cert.CertificateException: No name matching api.weibo.com found; nested excepti ...

  6. 【Block-Level Verification】 芯片开发通识_验证目标_ 验证语言_ 验证职业前景 _挑战和瓶颈_验证周期_功能描述文档_验证计划_回归测试_硅后测试_逃逸分析...

    SystemVerilog验证通识 1. 芯片开发概述 不同于通用电路,专用集成电路为了专门解决或者优化相关工程问题,例如专用算法的电路实现,如芯片里加入人工智能处理单元,为CPU\GPU减负,目的是 ...

  7. http三次握手_【吊打面试,击中要害】http三次握手四次挥手,https证书验证阶段和数据传输阶段...

    阅读文本大概需要3分钟. PPT: Jenkins与项目构建部署工具集成 0x01:tcp三次握手,四次挥手 三次握手(Three-way Handshake),是指在建立一个TCP连接时候,需要客户 ...

  8. Java nginx 双向ssl_使用Nginx实现HTTPS双向验证的方法

    https单向验证应用广泛想必大家都很熟悉,我已经在一篇博文中分享过,这次来看看Nginx如何实现双向验证. 单向验证与双向验证的区别: 单向验证: 指客户端验证服务器端证书,服务器并不需要验证客户端 ...

  9. Office文档上传后实时转换为PDF格式_图片文件上传后实时裁剪_实现在线预览Office文档

    Office文档上传后实时转换为PDF格式_图片文件上传后实时裁剪 前置条件 安装LibreOffice 安装OpenOffice 安装Unoconv 安装ImageMagick.x86_64 安装G ...

  10. 21天Jmeter打卡Day17 后置处理器_JSON_正则表达式_边界提取器_完成删除场景模拟测试

    1天Jmeter打卡Day17 后置处理器_JSON_正则表达式_边界提取器_完成删除场景模拟测试 https://www.jianshu.com/p/5c1d64e5d724 Json提取器见Day ...

最新文章

  1. 使用正则表达式抽取新闻/BBS网页发表时间
  2. 牛!Python 也能实现图像姿态识别溺水行为了!
  3. 15+ tar command usages with examples – Unix/Linux--reference
  4. HTML 转 PDF 之 wkhtmltopdf
  5. 小程序生成海报 详解
  6. 2021-05-15
  7. 手工matlab下K-means聚类算法实现而不是调用库函数
  8. 【python】获取http响应
  9. 拓端tecdat|R语言分布滞后线性和非线性模型(DLNM)分析空气污染(臭氧)、温度对死亡率时间序列数据的影响
  10. Mysql之insert,update,delete
  11. 单片机知识点总结框图_89C51单片机的结构框图及原理解析
  12. 地震matlab频域分析,MATLAB在地震数据分析中的应用
  13. 618的优惠券去哪了?
  14. 高中英语单词名词分类
  15. UVC之MJPEG流
  16. 【技巧】如何搜索公众号内文章
  17. [二级域名映射端口][Ngins端口映射]腾讯云二级域名映射端口
  18. 迪杰斯特拉--链式向前星
  19. latex自动编译 (ubuntu/win)
  20. 基于词频求两篇从文件读入的英文文章的相似度

热门文章

  1. HTC Vive手柄实现在平面上划线
  2. Python 操作快捷键
  3. Atitit 数据库对比较 oracle mysql pgsql 目录 1.1. 跨机器跨库mysql vs pgsql 1 1.2. 动态增加列 pgzhichi 1 1.3. Cte 1 1.4
  4. Atitit 数据join 的原理与java实现 Atitit join表连接的原理与实现 13、SQL Server 表连接的三种方式   (1) Merge Join   (2) Nested
  5. Atitit.jsou html转换纯文本 java c# php
  6. paip.提升开发效率-----vs2010源码选择字串高亮
  7. 一封来自华尔街 Quant 的信
  8. 基于 Token 的身份验证
  9. (转)比特币核心钱包(Bitcoin Core)入门使用教程
  10. Julia :PyPlot的plot_date