HTTP协议知识总结

更好的浏览体验: http://jie12366.xyz:8081/#/users/11/articles/59

HTTP 1.0

HTTP 1.0的问题

HTTP 1.0中,每一个请求都要开一个连接,请求结束,断开连接。这样的协议有两个问题

  • (1)性能问题:每次请求都打开一个新的连接,因为连接数有限,而且连接的建立和断开都很耗时(可能一个页面就会有几十个请求)。
  • (2)服务器推送问题:服务器无法主动向客户端推送消息。

Keep-Alive机制

为了解决一个请求完成后连接立即断开的问题,引入了Keep-Alive(保持心跳)机制。客户端在HTTP请求头部加上一个字段Connection:Keep-Alive。服务器端收到带有这样的字段的请求后,会维护一个Keep-Alive timeout参数,服务器在处理完请求后,不会立即断开连接,而是会保持连接,如果在timeout时间内都没有新的请求,那么服务器才会关闭这个连接。

HTTP 1.1

连接复用机制

HTTP 1.1将连接复用变成了默认的了,就算不设置字段Connection:Keep-Alive,请求完后也不会立即关闭连接。要想连接不复用,需要设置字段Connection:Close。

Pipeline和Head-of-line Blocking(队头阻塞)问题

为了让请求变为并发,引入了Pipeline机制,使得一个请求发出之后,在未收到响应之前,可以立即发送第二个请求。但是这里有个致命的问题,也就是Head-of-line Blocking(队头阻塞)问题。虽然Pipeline机制可以让请求并发,但是为了让请求和响应能配对,响应并不能并发。返回的响应需要按照先进先出的(类似队列)的顺序,所以如果第一个响应由于某些原因,会导致后面的响应会被阻塞。

服务器推送

  1. 客户端定期轮询:客户端每隔一段时间向服务器发送一个请求,如果服务器有消息就返回(效率较低,不建议)。
  2. WebSocket:这是一种基于TCP的可全双工通信的协议,可实现服务器主动推送。
  3. HTTP长轮询:保持一个HTTP长连接,如果服务器有新消息,就返回。如果在约定的时间还没有消息,服务器就返回一个空消息,然后客户端关闭该连接,再发起一个新的连接。

HTTP/2

由于HTTP 1.1不够完善,人们就想办法去提高性能,从而出现了HTTP/2.

与HTTP 1.1兼容

由于HTTP 1.1的应用已成主流,所以想要替代它几乎不可能,所以只能向它兼容。其实HTTP/2与HTTP1.1并不是平级的,HTTP/2是介于HTTP1.1与TCP之间的一个转换层。

二进制分帧

为了解决队头阻塞的问题,HTTP/2将一个请求的报文转换成二进制并分成多个帧来进行传输。由于请求和响应都可以乱序的发送,所以需要给每个请求或响应带上一个ID,好让他们匹配。二进制分帧其实并没有完全解决队头阻塞的问题,它只是把这个问题转移到了TCP层面(只要使用TCP协议,为了保证可靠性,采用先进先出,就一定会有队头阻塞的问题)。如果想要彻底解决队头阻塞的问题,只能不使用TCP协议,那就是Google提出的QUIC协议。

SSL/TLS

对称加密的问题

想要传输过程中信息加密,那么采用对称加密是很安全的。服务器和客户端都用同一个密钥对数据进行加密解密。这里面有个问题就是这个密钥要怎么在服务器和客户端之间传输呢?不急,咱先来看看双向非对称加密。

双向非对称加密

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i6a05pbf-1576491246600)(https://i.loli.net/2019/12/16/Sy3d8zoXGwYup9T.png)]

如图所示,客户端和服务器各自准备一对公钥密钥对。客户端向发送消息时,先用自己的私钥进行签名,并用服务器的公钥来对信息进行加密。服务器收到消息后,用自己的私钥来对消息解密,并用客户端的公钥来验证签名(签名可以证明这个消息是客户端发送的,且不可抵赖)。服务器向客户端发送消息也是一样的过程。
这里涉及到四个概念,其实就是两种(签名和验签、加密和解密)。

  • 签名和验签:私钥签名,公钥验签,可以防止第三方进行篡改(如果被篡改,验签则不能通过),也可以防抵赖(只有私钥可以签名)。
  • 加密和解密:公钥加密,私钥解密,可以防止第三方窃取信息,即使第三方截取到了传输的信息,没有私钥,也无法解密。

单向非对称加密

对于安全性要求特别高的场景,比如个人网银等,一般都会给用户一个U盾之类的东西,里面就是客户端的公钥和私钥,这样就可以做到双向非对称加密。但对于一般的场景,服务器并不需要去验证客户端的合法性,只要客户端验证服务器的合法性即可。这样就可以使用单向非对称+对称加密来保证传输的安全性。这也是SSL的原型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uopir2Ch-1576491246603)(https://i.loli.net/2019/12/16/uIpKHSJVTR9xta8.png)]

中间人攻击

中间人通过伪造服务器的公钥,然后与客户端进行通信。造成这个问题的原因是客户端不能验证服务器的公钥的合法性,所以需要数字证书。

数字证书

引入一个中间机构CA,服务器先把公钥发给CA,CA给服务器颁发一个数字证书(相当于服务器的身份证),然后服务器将这个证书发给客户端,客户端可以验证这个证书是否是服务器下发的,并可以从证书中获取服务器的公钥。数字证书是怎么验证的呢?数字证书是通过CA的私钥签名生成的,如果被伪造了,那么CA的公钥将无法进行验签。那么如果这个CA机构是伪造的呢,那咋办?

根证书

为了验证CA的合法性,所以需要由CA的上一级给CA颁发证书,最顶级的就是根证书了。至于根证书,我们只能无条件信任,它是由世界上公认的一些机构颁发的,并在用户的操作系统、浏览器发布的时候嵌进去的。如果你信任这个操作系统或浏览器,也就信任了这个根证书。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7jb0nsvJ-1576491246604)(https://i.loli.net/2019/12/16/TDoNhpSIOQfGCJm.png)]

可以看一下Google网站的证书,有三级,www.google.com是Google网站自己的证书,它的CA机构是GTS CA 101,它的Root CA是GlobalSign。

SSL/TLS协议

看一下SSL/TLS协议的四次握手。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xLWWfSik-1576491246606)(https://i.loli.net/2019/12/16/ZBrJgDx2shWbQGe.png)]

握手完成后,对称密钥的传输也完成了。然后客户端和服务器就可以基于对称加密来进行加密传输了(通过SSL的握手解决了对称密钥的传输问题)。

HTTPS

HTTPS传输过程

HTTPS = HTTP + SSL/TLS。所以HTTPS的传输过程如下,先建立TCP连接,在经过SSL/TLS四次握手,就可以进行HTTPS的对称加密传输了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WK4RYZVR-1576491246606)(https://i.loli.net/2019/12/16/qgRJHBT2p8x1hAw.png)]

SSL/TLS协议与HTTP/2协议一样,也是基于TCP和HTTP之间的,所以它两都是可选的。选了SSL/TLS,那就是HTTPS了。

HTTPS在抓包中明文

这个抓包只限于在本机抓包,如果是第三方抓包(比如黑客),那看到的肯定就是加密的密文了(不然要我HTTPS有何用)。

其实这个抓包软件就相当于中间人攻击中的中间人,伪造了一个CA证书(这里客户端为什么会信任呢,哈哈哈,因为是用户自己同意的,用户自己在计算机安装了一个抓包软件自己的根证书,因为客户端会无条件信任根证书,那么抓包软件伪造了CA证书肯定也会被信任啦。)

抓包软件截取了客户端请求,然后向服务器发送这个请求进行握手,获取到服务器的CA证书,再通过根证书解密获取到服务器的公钥,就可以伪造证书啦。抓包软件利用这个伪造的CA证书获取了客户端的信任,并同时冒充客户端和服务器(这就是中间人)。所以抓包软件在这里属于应用层的,而HTTPS加密是在传输层加密(在应用层肯定不加密(除非应用层自己手动加密)啦,因为是应用层发送的数据),所以在抓包软件中看到的肯定是明文信息啦。

https的加密没有安全问题,但它只是用来防止通信过程中被第三方获取明文(在通信的双方看到的肯定是明文啦)。如果黑客能直接控制通信的双方(你的电脑,或服务器),那么黑客肯定能看到https明文的。

TCP协议

可靠的传输

可靠传输的三个语义

  • 数据包不丢失。通过ACK确认 + 丢失重发来保证数据包不丢失。
  • 数据包不重复。根据已确认的ACK,将ACK序列之前的数据包直接丢弃,保证不重复。
  • 时序不错乱。服务器按照数据包的编号来进行ACK确认,如果前面有一个数据包没收到,后面的不会被确认,直到等待超时重发,后面的数据包也会被全部重发(可用第二种方式去重)。

TCP的连接状态机

这图有点复杂,懒得画了,网上找了一张。
在这里插入图片描述

TCP状态及其描述如下表。

状态描述
LISTEN等待来自远程TCP应用程序的请求
SYN_SENT发送连接请求后等待来自远程端点的确认。TCP第一次握手后客户端所处的状态
SYN-RECEIVED该端点已经接收到连接请求并发送确认。该端点正在等待最终确认。TCP第二次握手后服务端所处的状态
ESTABLISHED代表连接已经建立起来了。这是连接数据传输阶段的正常状态
FIN_WAIT_1等待来自远程TCP的终止连接请求或终止请求的确认
FIN_WAIT_2在此端点发送终止连接请求后,等待来自远程TCP的连接终止请求
CLOSE_WAIT该端点已经收到来自远程端点的关闭请求,此TCP正在等待本地应用程序的连接终止请求
CLOSING等待来自远程TCP的连接终止请求确认
LAST_ACK等待先前发送到远程TCP的连接终止请求的确认
TIME_WAIT等待足够的时间来确保远程TCP接收到其连接终止请求的确认

TCP建立连接的三次握手

下图显示了TCP三次握手的过程,以及客户端和服务端状态的变化
在这里插入图片描述
为什么需要三次握手呢,因为前两次握手只能保证客户端的发送和接收能力没问题,但此时服务器只知道自己的接收能力没问题,需要第三次握手来确认服务器的发送能力也是没问题的。

TCP断开连接的四次挥手

下图显示了一次典型的TCP四次挥手的过程,以及主动关闭方和被动关闭方的状态变化。在图中是客户端主动断开了连接,这里只是举个例子,服务端一样可以主动断开连接。
在这里插入图片描述
为什么是四次挥手,因为如果只进行了1、2次。由于TCP是全双工的,可以处于Half-Close状态,此时就是处于Half-Close状态,客户端到服务器的通道已经关闭,服务器到客户端的通道还没关闭,所以需要第三次和第四次来完全关闭连接。

TIME_WAIT状态

维持TIME_WAIT有两个原因:

  1. 可靠地实现TCP的全双工连接终止。
    在四次挥手中,假设最后的ACK丢失了,被动关闭方会重发FIN。主动关闭端必须维护状态,来允许被动关闭方重发最后的ACK;如果它没有维护这个状态,将会对重发FIN返回RST,被动关闭方会认为这是个错误。如果TCP正在执行彻底终止数据流的两个方向所需的所有工作(即全双工关闭),则必须正确处理这四个段中任何一个的丢失。所以执行主动关闭的一方必须在结束时保持TIME_WAIT状态:因为它可能必须重传最后的ACK。
  2. 允许旧的重复数据段在网络中过期
    由于可能会有的数据在网络中还没被接收,可能会被新连接给接收,这样就会造成问题。TCP定义了一个MSL值(默认是120S),也就是一个数据在网络中停留的最长时间不能超过这个时间。但为什么TIME_WAIT的等待时间是MSl * 2呢,因为第三次可能会发生重传,而第三次重传+第四次发送的时间最长是MSL * 2,所以需要让客户端在TIME_WAIT状态等待MSL * 2的时间。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值