AboutFE icon indicating copy to clipboard operation
AboutFE copied to clipboard

2、HTTPS/HTTP/HTTP2 工作原理及通信、网络协议

Open CodingMeUp opened this issue 7 years ago • 15 comments

HTTPS: 1、HTTPS的工作原理

HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息。TLS/SSL协议不仅仅是一套加密传输的协议,更是一件经过艺术家精心设计的艺术品,TLS/SSL中使用了非对称加密,对称加密以及HASH算法。握手过程的具体描述如下:

1.浏览器将自己支持的一套加密规则发送给网站。

2.网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。

3.浏览器获得网站证书之后浏览器要做以下工作:
a) 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。
b) 如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。
c) 使用约定好的HASH算法计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。

4.网站接收浏览器发来的数据之后要做以下的操作:
a) 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。
b) 使用密码加密一段握手消息,发送给浏览器。

5.浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。

这里浏览器与网站互相发送加密的握手消息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据,为后续真正数据的传输做一次测试。另外,HTTPS一般使用的加密与HASH算法如下:

非对称加密算法:RSA,DSA/DSS
对称加密算法:AES,RC4,3DES
HASH算法:MD5,SHA1,SHA256

image

CodingMeUp avatar Nov 15 '17 06:11 CodingMeUp

HTTPS协议和HTTP协议的区别:

  • https协议需要到ca申请证书,一般免费证书很少,需要交费。
  • http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
  • http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。
  • http的连接很简单,是无状态的 。无状态的意思就是给他一样的参数你要有一样的结果,通过增加cookie和session机制,现在的网络请求其实是有状态的
  • HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议, 要比http协议安全

CodingMeUp avatar Nov 15 '17 06:11 CodingMeUp

TCP 3次握手 1、建立连接协议(三次握手)

(1)客户端发送一个带SYN标志的TCP报文到服务器。这是三次握手过程中的报文1。 (2)服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN标志。因此它表示对刚才客户端SYN报文的回应;同时又标志SYN给客户端,询问客户端是否准备好进行数据通讯。 (3)客户必须再次回应服务段一个ACK报文,这是报文段3。 image

为什么需要“三次握手”

在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。在另一部经典的《计算机网络》一书中讲“三次握手”的目的是为了解决“网络中存在延迟的重复分组”的问题。这两种不用的表述其实阐明的是同一个问题。

谢希仁版《计算机网络》中的例子是这样的,“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”。 主要目的防止server端一直等待,浪费资源。

CodingMeUp avatar Nov 15 '17 06:11 CodingMeUp

连接终止协议(四次挥手) 由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

(1) TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送(报文段4)。 (2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。 (3) 服务器关闭客户端的连接,发送一个FIN给客户端(报文段6)。 (4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。

image 为什么需要“四次挥手”

那可能有人会有疑问,在tcp连接握手时为何ACK是和SYN一起发送,这里ACK却没有和FIN一起发送呢。原因是因为tcp是全双工模式,接收到FIN时意味将没有数据再发来,但是还是可以继续发送数据。

总结

TCP三次握手:1、客户端发送syn包到服务器,等待服务器确认接收。2、服务器确认接收syn包并确认客户的syn,并发送回来一个syn+ack的包给客户端。3、客户端确认接收服务器的syn+ack包,并向服务器发送确认包ack,二者相互建立联系后,完成tcp三次握手。四次握手就是中间多了一层 等待服务器再一次响应回复相关数据的过程

三次是最少的安全次数,两次不安全,四次浪费资源

CodingMeUp avatar Nov 15 '17 06:11 CodingMeUp

当我们在浏览器中输入 www.baidu.com/** 访问 百度的时候浏览器做了哪些事情

  1. 首先 Chrome 搜索自身的 DNS 缓存。(如果 DNS 缓存中找到百度的 IP 地址,就跳过了接下来查找 IP 地址步骤,直接访问该 IP 地址。)
  2. 搜索操作系统自身的 DNS 缓存。(浏览器没有找到缓存或者缓存已经失效) 读取硬盘中的 host 文件,里面记录着域名到 IP 地址的映射关系,Mac 电脑中位于 /etc/hosts。(如果前1.2步骤都没有找到)
  3. 浏览器向宽带运营商服务器或者域名服务器发起一个 DNS 解析请求,这里服务器有两种方式解析请求,这在稍后会讲到,之后浏览器获得了百度首页的 IP 地址。
  4. 拿到 IP 地址后,浏览器就向该 IP 所在的服务器建立 TCP 连接(即三次握手)。
  5. 连接建立起来之后,浏览器就可以向服务器发起 HTTP 请求了。(这里比如访问百度首页,就向服务器发起 HTTP 中的 GET 请求)
  6. 服务器接受到这个请求后,根据路径参数,经过后台一些处理之后,把处理后的结果返回给浏览器,如果是百度首页,就可以把完整的 HTML 页面代码返回给浏览器。
  7. 浏览器拿到了百度首页的完整 HTML 页面代码,内核和 JS 引擎就会解析和渲染这个页面,里面的 JS,CSS,图片等静态资源也通过一个个 HTTP 请求进行加载。
  8. 浏览器根据拿到的资源对页面进行渲染,最终把完整的页面呈现给用户。如果浏览器没有后续的请求,那么就会跟服务器端发起 TCP 断开(即四次挥手)。

https://segmentfault.com/a/1190000006879700

CodingMeUp avatar Nov 15 '17 07:11 CodingMeUp

HTTP

HTTP地位

Web使用一种名为HTTP(HyperText Transfer Protocol,超文本传输协议)的协议作为规范,完成从客户端到服务器等一系列运作流程。而协议是指规则的约定。可以说,Web是建立在HTTP协议上通信的。

HTTP最初的目的是为了让研究者共享知识信息,所以它的主要作用就是文档传输,它是一种用于传输文档的协议。 HTTP是不保存状态的协议,既无状态协议,协议本身对于请求或响应之间的通信状态不进行保存,因此连接双方不能知晓对方当前的身份和状态。这也是Cookie技术产生的重要原因之一:客户端的状态管理。浏览器会根据从服务器端发送的响应报文内 Set-Cookie 首部字段信息自动保持 Cookie。而每次客户端发送 HTTP 请求,都会在请求报文中携带 Cookie,作为服务端识别客户端身份状态的标识

TCP/IP 协议族

TCP/IP 协议族是Internet最基本的协议,HTTP协议是它的一个子集。TCP/IP协议族按层次分为以下四层:

  1. 应用层

应用层规定了向用户提供应用服务时通信的协议,如:

TCP/IP 协议族内预存了各类通用的应用服务协议。比如,FTP(File Transfer Protocol,文件传输协议)和DNS(Domain Name System,域名系统)服务就是其中的两类以及HTTP协议。

DNS域名系统提供域名(如:www.baidu.com)到IP地址(如:119.75.217.109)之间的解析服务

  1. 传输层

传输层对接上层应用层,提供处于网络连接中两台计算机之间的数据传输所使用的协议。

在传输层有两个性质不同的协议:

  • TCP(Transmission Control Protocol,传输控制协议)
  • UDP(User Data Protocol,用户数据报协议)。

TCP协议是全双工的,即发送数据和接收数据是同步进行的,就好像我们打电话一样,说话的同时也能听见。TCP协议在建立和断开连接时有三次握手和四次挥手,因此在传输的过程中更稳定可靠但同时就没UDP那么高效了。

UDP协议是面向无连接的,也就是说在正式传递数据之前不需要先建立连接。UDP 协议不保证有序且不丢失的传递到对端,也就是说不够稳定,但也正因如此,UDP协议比TCP更加高效和轻便。

  1. 网络层

网络层规定了数据通过怎样的传输路线到达对方计算机传送给对方(IP协议等)。

与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的所用就是在众多的选项内选择一条传输路线。就跟携程提供的回家路线图作用一样。

  1. 链路层

用来处理连接网络的硬件部分,包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网络适配器,即网卡,以太网),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在链路层的作用范围之内。

发送端在层与层之间传输数据时,每经过一层时会被打上一个该层所属的首部信息。反之,接收端在层与层之间传输数据时,每经过一层时会把对应的首部信息去除。

几种链接的区别

  • 串行连接: HTTP有无连接的特性,即每次连接只能处理一个请求,收到响应后立即断开连接。HTTP/1.0 版本(称为串行连接或短连接、短轮询)中每次HTTP通信后都要断开TCP连接,所以每个新的HTTP请求都需要建立一个新的连接。但在现在网站动则几十条HTTP请求的情况下,很容易达到浏览器请求上限,并且每次请求都建立新的tcp连接(每次都有三次握手四次挥别)极大的增加了通信开销

  • 持久连接: 为解决这个问题,有人提出了持久连接(也叫长连接、长轮询)。一定时间内,同一域名下的HTTP请求,只要两端都没有提出断开连接,则持久保持TCP连接状态,其他请求可以复用这个连接通道。HTTP/1.1 实现并默认了所有连接都是持久连接,这样客户端发起多个HTTP请求时就减少了TCP握手造成的网络资源和通信时间的浪费。但是持久连接采用阻塞模式,下次请求必须等到上次响应返回后才能发起,如果上次的请求还没返回响应内容,下次请求就只能等着(就是常说的线头阻塞)。

  • 管道化持久连接: 管道化则可以不用等待响应返回而发送下个请求并按顺序返回响应,现代浏览器并未默认开启管道化。(这方面收集到的资料有限不多说了)

  • HTTP/2.0多路复用: 每个HTTP请求都有一个序列标识符,这样浏览器可以并发多个请求,服务器接收到数据后,再根据序列标识符重新排序成不同的请求报文,而不会导致数据错乱( 细节参照此文)。同样,服务端也可以并发返回多个响应给浏览器,浏览器收到后根据序列标识重新排序并归入各自的请求的响应报文并且同一个域名下的所有请求都复用同一个TCP连接,极大增加了服务器处理并发的上限

  • WebSocket: WebSocket是HTML5提出的一种客户端和服务端通讯的全双工协议由客户端发起请求,建立连接之后不仅客户端可以主动向服务端发送请求,服务端可以主动向客户端推送信息,推拉结合

看图区分三种链接: 如图中(a):串行连接每次发起请求都必须建立新的tcp连接。 如图中(b):持久连接多个http请求可以复用同一个tcp连接,但是下次请求必须在上次响应返回之后进行。 如图中(c):管道化持久连接也可以复用同一个tcp连接,并且可以不用等待发出多个http请求,但是响应必须按顺序返回。

HTTP/2.0

在 HTTP/2 中,有两个非常重要的概念,分别是帧(frame)和流(stream),理解这两个概念是理解下面多路复用的前提。 帧代表数据传输的最小的单位,每个帧都有序列标识表明该帧属于哪个流,流也就是多个帧组成的数据流,每个流表示一个请求。这里有个chrome扩展程序,可以方便的查看当前网站的HTTP请求版本(安装后在chrome开发工具-Network-在Name/Size/Time表格头右键选择Procotol,即可查看协议版本)。

  • 新的二进制格式: HTTP/1.x的解析是基于文本的。基于文本协议的解析存在天然缺陷,文本的表现形式有多样性,要做到全面性考虑的场景必然很多。二进制则不同,只识别0和1的组合。基于这种考虑HTTP/2.0的协议解析采用二进制格式,方便且强大。
  • 多路复用: HTTP/2.0支持多路复用,这是HTTP/1.1持久连接的升级版。多路复用,就是在一个 TCP 连接中可以存在多条流,也就是可以发送多个请求,服务端则可以通过帧中的标识知道该帧属于哪个流(即请求),通过重新排序还原请求。多路复用允许并发的发起多个请求,每个请求及该请求的响应不需要等待其他的请求或响应,避免了线头阻塞问题。这样某个请求任务耗时严重,不会影响到其它连接的正常执行,极大的提高传输性能。
  • 头部压缩: HTTP/1.x的请求和响应头部带有大量信息,而且每次请求都要重复发送,HTTP/2.0使用encoder来减少需要传输的头部大小,通讯双方各自cache一份头部 fields表,既避免了重复头部的传输,又减小了需要传输的大小。
  • 服务端推送: 这里的服务端推送指把客户端所需要的css/js/img资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤(从缓存中取)。

HTTP/3.0

HTTP/2.0 使用了多路复用,一般来说同一域名下只需要使用一个 TCP 连接。但当这个连接中出现了丢包的情况,那就会导致整个 TCP 都要开始等待重传,也就导致了后面的所有数据都被阻塞了。反而对于 HTTP/1.0 来说,可以开启多个 TCP 连接,出现丢包反倒只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。 出现包阻塞的原因是因为底层TCP协议导致的问题,但是修改TCP协议是不现实的问题,就像typeof null === 'object'一样,修改这个问题会导致出现更多的问题。既然不能修改你,那就另起一个协议取代你。Google 基于 UDP 协议推出了一个的 QUIC 协议,并且使用在了 HTTP/3 上。

QUIC 基于 UDP,但是UDP本身存在不稳定性等诸多问题,所以QUIC在UDP的基础上新增了很多功能,比如多路复用、0-RTT、使用 TLS1.3 加密、流量控制、有序交付、重传等等功能。优点诸多,参考这里:

  • 避免包阻塞: 多个流的数据包在TCP连接上传输时,若一个流中的数据包传输出现问题,TCP需要等待该包重传后,才能继续传输其它流的数据包。但在基于UDP的QUIC协议中,不同的流之间的数据传输真正实现了相互独立互不干扰,某个流的数据包在出问题需要重传时,并不会对其他流的数据包传输产生影响。
  • 快速重启会话: 普通基于tcp的连接,是基于两端的ip和端口和协议来建立的。在网络切换场景,例如手机端切换了无线网,使用4G网络,会改变本身的ip,这就导致tcp连接必须重新创建。而QUIC协议使用特有的UUID来标记每一次连接,在网络环境发生变化的时候,只要UUID不变,就能不需要握手,继续传输数据。

CodingMeUp avatar May 27 '20 16:05 CodingMeUp

其他部分 报文, 代理服务器等 https://juejin.im/post/5cd0438c6fb9a031ec6d3ab2

CodingMeUp avatar May 27 '20 16:05 CodingMeUp

缓存 3XX https://aotu.io/notes/2016/01/28/3xx-of-http-status/index.html

CodingMeUp avatar May 27 '20 16:05 CodingMeUp

keep - alive https://lotabout.me/2019/Things-about-keepalive/

CodingMeUp avatar May 27 '20 16:05 CodingMeUp

https://byvoid.com/zhs/blog/http-keep-alive-header/

CodingMeUp avatar May 27 '20 16:05 CodingMeUp

https https://juejin.im/post/5ca6a109e51d4544e27e3048

CodingMeUp avatar May 27 '20 16:05 CodingMeUp