查看原文
其他

网络通信中的几种握手,甩出这张脑图,都懂了!

The following article is from 前端劝退师 Author 前端劝退师

前言

看了本《网络是怎样连接的》与两本HTTP相关的专栏。

避免看了即忘,就画了一张XMind图:

值得深入的问题太多了,今儿就先来讲讲:Web中的几种“握手”

1. 不止一种握手

在早期的网络传输中,也就存在TCP协议需要“握手”的过程,但早期的协议有一个缺陷:通信只能由客户端发起,做不到服务器主动向客户端推送信息。

于是WebSocket 协议在 2008 年诞生,2011 年成为国际标准。所有浏览器都已经支持了。

而随着SSL/TLS的完善,存在已久的安全版网络协议:HTTPS也是迸发式发展。

最后前端领域的协议握手便成了三分天下:

  1. TCP三次握手,归HTTP
  2. TLS握手,归HTTPS
  3. WebSocket握手,基于TCP协议,都能用。

2. TCP三次握手的终极意义

在我之前的文章:《「真香警告」重学 TCP/IP 协议 与三次握手 》

也详细的讲述过TCP三次握手,但那时我未明确意识到其深刻含义。

就和大家一样,只在面试前会记得,过后即忘。

直到我看到《网络是怎样连接的》中的一段话:

在实际的通信中,序号并不是从 1 开始的,而是需要用随机数计算出一个初始值,这是因为 如果序号都从 1 开始,通信过程就会非常容易预测,有人会利用这一点来发动攻击。

但是如果初始值是随机的,那么对方就搞不清楚序号到底是从 多少开始计算的,因此需要在开始收发数据之前将初始值告知通信对象。

你品,你细品。三次握手不就是相互试探暗号,来确定是不是对的人吗?

2.1 知识补充:一个网络包的最大长度

计算每个网络包能容纳的数据长度,协议栈会根据一个叫作 MTU的参数来进行判断。

MTU表示一个网络包的最大长度,在以太网中一般是1500字节

MTU是包含头部的总长度,因此需要从MTU减去头部的长度,然后得到的长度就是一个网络包中所能容纳的最大数据长度,这一长度叫作MSS

由上两图可知,MSS值是1460(1500-40)字节,其中:

  1. TCP固定头部20字节。
  2. IP固定头部20字节。
  3. TCP头部最长可以达到60字节。

3. TLS握手:HTTPS的核心

HTTPS 其实是一个“非常简单”的协议,RFC 文档很小,只有短短的 7 页,里面规定了新的协议名“https”,默认端口号 443,至于其他的什么请求 - 应答模式、报文结构、请求方法、URI、头字段、连接管理等等都完全沿用 HTTP,没有任何新的东西。---- 《透视HTTP协议》

感兴趣的可以到这里看看:链接:https://tools.ietf.org/html/rfc2818

3.1 TLS/SSL究竟是啥?

很多人看到TLS/SSL这对词就开始蒙圈了。实际上,这两个东西是一个玩意儿:

1999 年改名:SSL 3 === TLS 1.0

目前运用最广泛的是TLS 1.2:

TLS 由记录协议、握手协议、警告协议、变更密码规范协议、扩展协议等几个子协议组成,综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术。

由于TLS/SSL 协议位于应用层和传输层 TCP 协议之间。TLS 粗略的划分又可以分为 2 层:

  1. 靠近应用层的握手协议 TLS Handshaking Protocols

  2. 靠近 TCP 的记录层协议 TLS Record Protocol

这个篇幅展开来写就太多了,我们先关心下TLS握手吧。

3.2 TLS握手详解

TLS 握手何时发生?:

  1. 每当用户通过HTTPS导航到网站并且浏览器首先开始查询网站的原始服务器时,就会进行TLS握手。
  2. 每当其他任何通信使用HTTPS(包括API调用和HTTPS查询上的 DNS)时,也会发生TLS握手。
  3. 通过 TCP 握手打开 TCP 连接后,会发生TLS 握手。

TLS 握手期间会发生什么?

TLS握手过程中,客户端和服务器将共同执行以下操作:

  • 指定将使用的 TLS 版本(TLS 1.0、1.2、1.3 等)
  • 确定将使用哪些加密套件。
  • 通过服务器的公钥和 SSL 证书颁发机构的数字签名来验证服务器的身份
  • 握手完成后,生成会话密钥以使用对称加密

加密套件决定握手方式:

摘自:《HTTPS 篇之 SSL 握手过程详解》[1]

TLS中有两种主要的握手类型:一种基于RSA,一种基于Diffie-Hellman。这两种握手类型的主要区别在于主秘钥交换和认证上。


秘钥交换身份验证
RSA 握手RSARSA
DH 握手DHRSA/DSA

主流的握手类型,基本都是基于RSA,所以以下讲解都基于RSA版握手。

整个流程如下图所示:具体流程描述:

  1. 客户端hello:客户端通过向服务器发送“问候”消息来发起握手。该消息将包括客户端支持的 TLS 版本,支持的加密套件以及称为“客户端随机”的随机字节字符串。
  2. 服务器hello:为回复客户端hello消息,服务器发送一条消息,其中包含服务器的SSL证书,服务器选择的加密套件和“服务器随机数”,即服务器生成的另一个随机字节串。
  3. 客户端发送公钥加密的预主密钥。
  4. 服务器用自己的私钥解密加密的预主密钥。
  • 客户端finished:客户端发送“完成”消息,该消息已用会话密钥加密。
  • 服务器finished:服务器发送一条用会话密钥加密的“完成”消息。
  • 握手完成,后续通过主密钥加解密。
  • 只有加密套件,讲解的话需要有抓包基础。改天,改天我一定讲。。。

    4. WebSocket握手

    WebSocket协议实现起来相对简单。它使用HTTP协议进行初始握手。成功握手之后,就建立了连接,WebSocket基本上使用原始 TCP 读取/写入数据。

    《图解HTTP》一书中的图讲的比较清楚:

    具体步骤表现是:

    1. 客户端请求:
    GET /chat HTTP/1.1Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==Sec-WebSocket-Protocol: chat, superchatSec-WebSocket-Version: 13Origin: http://example.com
    1. 服务端响应:
    HTTP/1.1 101Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=Sec-WebSocket-Protocol: chat

    4.1 Websocket全双工通信

    Websocket协议解决了服务器与客户端全双工通信的问题。

    那什么是单工、半双工、全双工通信?

    类型能力
    单工信息单向传送
    半双工信息能双向传送,但不能同时双向传送
    全双工信息能够同时双向传送

    4.2 WebsocketSocket区别

    可以把WebSocket想象成HTTP应用层),HTTPSocket什么关系,WebSocketSocket就是什么关系。

    1. WebSocketHTTP的关系

    相同点

    1. 都是一样基于TCP的,都是可靠性传输协议。
    2. 都是应用层协议。

    不同点

    1. WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息。HTTP是单向的。
    2. WebSocket是需要握手进行建立连接的。

    2. Socket是什么?

    Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。

    在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

    4.3 扩展知识:Socket.IO的七层降级

    GolangJava Spring等框架中,websocket都有一套实现API

    Socket.IO 由两部分组成:

    1. 一个服务端用于集成 (或挂载) 到 Node.JS HTTP 服务器:socket.io
    2. 一个加载到浏览器中的客户端:socket.io-client

    很多人以为Socket.IO只是WebSocketXHR长轮询。

    实际上,Socket.io有很多传输机制:

    1. WebSockets2. FlashSocket3. XHR长轮询4. XHR部分流:multipart/form-data5. XHR轮询6. JSONP轮询7. iframe

    得益于这么多种传输机制,Socket.io兼容性完全不用担心。

    5. 扩展:HTTPSHTTP 核心区别

    上面讲到 Socket是什么?,有一点我忘了讲:

    HTTPSHTTP 核心区别在于两点:

    1. HTTP 下层的传输协议由 TCP/IP 换成了 SSL/TLS
    2. 收发报文不再使用 Socket API,而是调用专门的安全接口。

    具体区别:

    1. HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
    2. HTTP是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 ssl 加密传输协议。
    3. HTTPhttps使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443
    4. HTTP的连接很简单,是无状态的。HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。

    后记及引用

    本篇引用了大量资料和专栏:

    1.《HTTPS 篇之 SSL 握手过程详解》[2] >
    2.《网络是怎样连接的》--户根勤 >
    3.[《图解 HTTP》--上野宣 ]
    4.[《透视 HTTP 协议》--罗剑峰]
    5.《What Happens in a TLS Handshake?》[3] >

    1. 《How to Use Websockets in Golang: Best Tools and Step-by-Step Guide》[4]



    后台回复“加群”,带你进入高手如云交流群


    推荐阅读:

    3.9折图书限时秒杀!当当网这次要被薅惨了

    手把手带你实操Serverless应用部署

    Kubernetes的架构为什么是这个样的?

    任何人都能看得懂的网络协议之ARP

    用好你的网络瑞士军刀netcat

    一次Linux系统被攻击的分析过程

    Linux下删除大量文件效率对比

    130 个相见恨晚的神器网站

    分享20个Linux命令小贴士与技巧

    一文带你彻底理解文件系统

    5G与Wi-Fi6空口技术对

    牛逼的Linux性能剖析—perf

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

    一文搞定 UDP 和 TCP 高频面试题!



    喜欢,就给我一个“在看”



    10T 技术资源大放送!包括但不限于:云计算、虚拟化、微服务、大数据、网络、Linux、Docker、Kubernetes、Python、Go、C/C++、Shell、PPT 等。在公众号内回复「1024」,即可免费获取!!

    : . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存