「网络通信基础」通俗易懂的讲解,让你彻底搞懂http各版本差异、https、数字证书等姿势

HTTP协议发展史

v2-9659d122f0993ba815e3c637661687ed_720w.jpg

随着网络技术的发展,1999 年设计的 HTTP/1.1 已经不能满足日常需求,于是当时Google开始推动下一代协议 SPDY 的制定,但是 SPDY 最终并未成为标准协议。由于 HTTP2 标准制定有 SPDY 开发组的参与,并且也参考了很多 SPDY 的设计,所以一般将 SPDY 视为 HTTP2 的前身。

到目前为止,HTTP协议主流版本一共有三个版本分别为 1.01.12(实际上很多企业连HTTP2都没有普及更不用提3.0)

HTTP1.0

HTTP1.0 存在的问题

  • 安全性差,内容以明文的形式进行传输

    HTTP2 时,数据是基于二进制协议格式传输的,在此之前都是基于明文协议进行传输。

  • 性能浪费,无法复用连接

    每次发送请求都需要建立一次TCP连接,而TCP的连接和释放的过程是需要时间成本的,这样会使网络的利用率变的很低。

  • 队头堵塞(head of line blocking)

    HTTP1.0 规定,下一个请求必须在上一个请求响应到达之后才能发送,如果上个请求响应还没回来,下个请求必须要等待 后面所有请求就会阻塞。

  • 服务端无法推送消息

    HTTP2前,服务端都是无法推送消息的

HTTP1.1

相比较 HTTP1.0 的一些新特性:

  • 长连接(连接复用)

    HTTP1.1 可以通过字段 Connection:Keep-Alive 建立长连接(长连接默认开启的),实现在一个TCP连接中传递多个HTTP请求和响应,极大的提高了网络利用率。客户端可以在请求头携带字段 Connection:false 来告知服务器关闭连接。
    服务端的连接数是有上限的,服务端可以通过 Keep-Alive:timeout 设置超时时间,当客户端在规定时间区间内未发起请求,将关闭该连接。

  • 引入pipeline机制(管道机制),提升HTTP请求发送效率

    虽然通过长连接实现了单个连接发送多个HTTTP请求,但是每个请求还是必须要等上个请求的响应返回后才能发送,为此引入 pipeline机制(如下图),即当发送请求时,不需要等该请求响应结果返回就可以直接发送下个请求和后面所有请求。

    src=http___img.it610.com_image_info8_bb6eefdbbc604454b33940d18db19e0a.jpg&refer=http___img.it610.jfif

    pipeline机制 也非 “银弹”,pipeline机制 要求 发送请求接收响应 的顺序要一致要先进先出,当依次发送A、B、C 三个请求时,必须保证接收响应的顺序为 A>B>C 。如果A请求的响应没有结束,就不能进行后面请求响应的接收处理,也会造成阻塞。由于 pipeline机制 也存在队头堵塞的问题,导致它也没有得到广泛的使用。

  • 断点续传(默认只支持断点下载)

    客户端从后端下载文件时,如果中途中断,再次建立连接时,客户端可以从上次中断的位置继续下载。实现原理是,客户端需要一边下载一边记录下载量,中断重新建立连接时,请求头新增 Range:first offset-last offset 字段去指定要获取哪个区间的数据,这样后端就只返回 first offsetlast offset 之间的数据

HTTP2

HTTP2在诞生前,HTTP1.1已经成为世界主流,所以HTTP2要兼容HTTP1.1标准,这意味着要面对着两大问题

  • 不能改变 “http://”“https://” 这个URL范式

  • 不能改变 http request / http response报文结构的通信模型,http协议应该是 “一来一回“,一个request 对应一个response

  • 兼容http1.1
    怎么样在不改变 request/response 的报文结构的情况下, 发明一个新的 HTTP2 协议。HTTP/2和HTTP1.1并不是平级位置,HTTP2位于HTTP1.1和TCP之间的协议,它相当于起了一个转换层的作用。

  • 多路复用
    即每个HTTP request可以共享连接,每个HTTP request都对应着一个ID,在每个连接中所有request混杂在一起。接收方可以根据request的id将其归属到各自不同的服务端请求中。

  • header压缩
    http request/responseheader 部分总是会携带大量重复的字段,http/2为了提高传输效率和性能,对header 部分进行压缩,客户端、服务器端各缓存一份索引表,在传输过一次后会根据header字段键值从索引表中查取。

  • 数据包二进制分帧 解决队头堵塞问题
    与HTTP1.X 不同 HTTP2基于二进制协议解析数据包,他会将数据包分为多个帧(数据块)发送
    http2只能降低对头堵塞的概率,仍然无法完全解决对头堵塞的问题,http1.1的popline机制必须按照顺序进行响应,并且每次发送/响应都是完整数据包,当某个响应阻塞后面所有响应都无法接收;http2分帧发送请求,响应顺序是乱序的,即便前面的请求发生阻塞也不会影响后面的请求。总之基于TCP就难免会发生对头堵塞的问题。

  • 服务器推送

HTTPS

由于http请求的无状态性和明文传输导致它有几大安全性问题

  • 通信内容被窃听,第三方可以截获并查看通信内容
  • 通信内容被篡改,第三方可以截获并修改通信内容
  • 通信身份被冒充,第三方可以冒充客户端和服务器端参与通信

要解决以下问题,我们要先弄清几个密码学基本概念

对称加密:使用相同的密钥对数据进行加密 / 解密操作

非对称加密:数据的加密解密操作是通过两个密钥完成的,即使用 公钥 进行加密,使用 私钥 进行解密

私钥:通过特殊算法得出的字符串

公钥:私钥经过特殊算法可以得到公钥,这个过程是不可逆的,即有了私钥可以计算出公钥,有公钥却无法计算出私钥

使用 对称加密 对报文进行加密

针对报文以明文传输的问题,可以使用 对称加密 对报文进行加密,服务端、客户端共享同一个密钥。客户端向服务器发送报文时,客户端会使用该密钥加密,服务端使用该密钥解密。相反,服务端向客户端发送报文时使用该密钥

这样报文被加密了,但是密钥的传输又成了一个新问题,怎么能保证通信时,密钥不会泄露。我可以使用 非对称加密(单向) 对密钥进行加密传输。
同时为了防止有三方冒充客户端或服务器端参与通信,引入了 签名机制,即报文发送方使用密钥签名,报文接收方使用密钥验签,检验发送者的身份。

双向非对称加密

1646317900(1).jpg
双向非对称加密通信双方各有一对公钥、私钥,如上图,客户端有一对公私钥(PubA、PriA),服务器端有一对公私钥(PubB、PriB),双方都保留各自私钥公开各自公钥。

双方通信会有两个操作:加密和解密、签名和验签

  • 加密和解密
    客户端发送报文时,使用服务端的 公钥PubB 进行加密,服务端使用自己的 私钥PriB 进行解密,反之服务器端响应报文时使用客户端的 公钥PubA 进行加密,客户端接收报文使用自己的 私钥PriA 进行解密

  • 签名和验签
    发送报文时,使用发送者的私钥进行签名,使用发送者的公钥进行验签。如果数据被篡改,验签不会通过。这样可以避免第三方篡改数据。过程时,客户端发送报文时,使用自己的私钥PriA签名,服务器端使用客户端的公钥PubA验签,反之同理。

即:自己私钥签名+对方的公钥加密 — 对方的公钥验签+自己的私钥解密

单向非对称加密

单向非对称加密 是B/S通信的主要形式,在互联网中,网站是开放的服务器无验证每个客户端的合法性,只有客户端可以验证服务器端的合法性。举个栗子,百度、淘宝此类网站是公开的,我们访问这些网站时需要验证其真实性、合法性,以防止被钓鱼窃取用户信息。

image.png

如上图,客户端与服务器端通信,客户端使用服务器的公钥对请求报文进行加密,服务器使用自己私钥解密,然后服务器以明文的形式向客户端响应报文。

这样看只实现了单向数据加密,怎么保证服务器端响应的报文不会被截获、篡改?

这个地方就用到了对称加密

image.png

  • 首先客户端和服务器会发送真实报文前,会先协商秘钥
    如上图,客户端在发送真实数据前,先使用服务器的 公钥PubB对称加密的密钥PriC 加密并发送给服务器端,服务器使用自己的 私钥PriB 解密,获取 密钥PriC ,并以明文形式通知客户端 “接收 对称加密密钥PriC 成功”。这样通信双方都知道了 对称加密密钥PriC

  • 使用对称加密,加密/解密报文
    客户端使用 密钥PriC 对报文加密并发送给服务器,服务端同样使用 密钥PriC 解密;服务端使用 密钥PriC 加密响应报文,客户端使用 密钥PriC 解密

上面这种 单向非对称加密+对称加密的通信模型 就是 SSL/TLS 的原型

CA机构和数字证书

聊CA机构和数字证书之前,先说下非对称加密的缺陷—容易找到第三方拦截攻击

服务器公钥是公开的,第三方可以截获并篡改服务器公钥与客户端进行通信骗取数据。客户端拿到服务器公钥,如何判断该公钥是合法服务器的而不是第三方的?

image.png

如上图,第三方参与通信,先冒充服务器,客户端以为第三方C为服务器,将自己公钥PubA发送给第三方C;然后第三方C冒充客户端向服务器发送自己公钥PubC成功骗到服务器的公钥PubB,第三方C接着冒充服务器给了客户端一个伪造公钥PubC

这样客户端与服务端都以为是在跟对方通信,实际整个过程都被第三方截获了。这个问题的根源,就是公钥是用明文传输,客户端无法判断公钥是不是目标服务器的,服务器无法判断公钥是不是真实客户端的,如何解决这个问题?

  • 服务端/客户端 不在发送公钥,而是发送 数字证书数字证书 是加强版的公钥
  • 数字证书 由CA机构颁发,客户端/服务器 拿到数字证书后通过CA机构验证真伪

数字证书颁发与验证

数字证书颁发
CA机构也是一对公、私钥,公钥时公开的私钥只有CA自己知道。服务器/客户端 向CA机构发送自己的信息和公钥,CA使用CA自己的私钥根据这些信息生成一个数字证书

数字证书验证
在B/S通信一方发送数字证书,另一方可以使用CA机构的公钥进行验证,如果有人伪造数字证书,就会验证失败。

image.png
如上图,服务器端/客户端先提交自己信息和公钥到CA机构,CA机构认证后返回一个数字证书,后面不在使用公钥而是使用数字证书进行通信。

CA机构的真伪

CA机构是分级别的,每级CA都有自己的数字证书,最顶级ROOT CA机构是世界公认的

image.png

如上图,证书的颁发和验证是相反的两个过程,都是一级级验证、一级级颁发

服务端向客户端发送数字证书,客户端带着服务端数字证书去 C3级CA机构 验证其合法性
客户端要验证C3级CA机构合法性,就要带着C3的证书去C2级CA机构验证,…一直遵循这个过程直到ROOT CA验证成功

最终在网络通信中,每个实体使用 数字证书 进行验证通信,而不是开始的公钥,这种标准的体系我们称之为 PKI(Public Key Infrastructure)

SSL/TLS

SSL中文名称为安全套接层,TLS中文名为传输层安全协议
https = http + SSL/TLS
SSL/TLS不仅支持http协议 同时还支持ftp等其他应用层协议,它位于应用层协议和TCP协议之间

SSL/TLS的四次握手

SSL/TLS协议为通信安全而生,在发送http请求需要先通过 SSL/TLS的四次握手 完成 身份校验、协商密钥等过程
image.png

  • 如上图,SSL/TLS 第一次握手客户端询问服务器端数字证书
  • SSL/TLS 第二次握手服务器端返回数字证书,客户端接收成功后开始验证证书合法性
  • SSL/TLS 第三次握手协商出密钥,客户端将对称加密密钥 进行加密后发送给服务器端
  • SSL/TLS 第四次握手服务器端向客户端发送 密钥接收成功的消息

https协议完整通信模型

https = tcp + SSL/TLS + http

image.png
完整的 https 通信过程要经过三个阶段

  • 1、TCP通过三次握手后建立连接
  • 2、通过SSL/TLS 验证通信对方身份并协商出对称加密密钥
  • 3、使用该秘钥,对该TCP连接的所有 http request/response 进行加密处理

其中1、2阶段在连接建立时只经过一次,之后如果断开连接,每个 http request/response 都只会经历3阶段 不会有太大的性能损耗问题。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享