Bootstrap

HTTPS(SSL/TLS握手过程)&TCP协议(三次握手四次挥手)

一、HTTPS握手过程

SSL/TLS 目的:加密、校验、证书

  1. 首先是tcp的三次握手建立连接
  2. client发送它支持的TLS版本、随机数client-random和它所支持的加密套件集合(clientHello)
  3. server收到信息,返回所支持的TLS版本,选取其中一个加密套件和随机数service-random(serverHello),随后把数字证书也发给服务端
  4. client验证证书有效性,并用client-random+service-random根据约定的加密算法生成会话密匙,并通过服务器公钥对其加密,发送给server
  5. server收到加密后的预主密钥,用私钥解密,得到预主密钥,根据约定的加密算法生成master-secret(会话密匙),然后发送预定成功

二、TCP连接的建立与释放

建立连接的三次握手

在这里插入图片描述

  1. 服务端开始监听某个端口,进入了LISTEN状态。
  2. 由客户端主动发起连接,这一过程由客户端执行connect来触发。将标志位 SYN置为1,随机生成一个序号seq=x , 自己变成了SYN-SENT状态。
  3. 服务端接收到,将SYN和ACK都置为1,随机生成一个序号seq=y,还生成一个确认号ack=对方序号+1,自己变成了SYN-RCVD。
  4. 客户端收到确认后,检查收到的ack是否为自己的序号+1,若没问题则将ACK置为1,将自己的序号值seq设为之前的序号加一,将自己的确认号ack置为对方序号+1,发给服务端,将自己变成了ESTABLISHED状态;服务端收到数据包之后,检查ack是否为自己序号+1,如果没问题也变成了ESTABLISHED状态。
    两方可以开始传输数据了。

另外需要提醒注意的是,从图中可以看出,SYN 是需要消耗一个序列号的,下次发送对应的 ACK 序列号要加1。
为什么呢?只需要记住一个规则:
凡是需要对端确认的,一定消耗TCP报文的序列号。
SYN 需要对端的确认, 而 ACK 并不需要,因此 SYN 消耗一个序列号而 ACK 不需要。
为什么是三次握手
● 第一次握手:证明了发送方能发数据
● 第二次握手:ACK确保了接收方能收数据,SYN确保了接收方能发数据
● 第三次握手:确保了发送方能收数据并能正确应答
为什么不是两次
根本原因: 无法确认客户端的接收能力。
分析如下:
如果是两次,你现在发了 SYN 报文想握手,但是这个包滞留在了当前的网络中迟迟没有到达,TCP 以为这是丢了包,于是重传,两次握手建立好了连接。
看似没有问题,但是连接关闭后,如果这个滞留在网路中的包到达了服务端呢?这时候由于是两次握手,服务端只要接收到然后发送相应的数据包,就默认建立连接,但是现在客户端已经断开了。
看到问题了吧,这就带来了连接资源的浪费。
为什么不是四次
三次握手的目的是确认双方发送和接收的能力,那四次握手可以嘛?
当然可以,100 次都可以。但为了解决问题,三次就足够了,再多用处就不大了。
三次握手过程中可以携带数据么
第三次握手的时候,可以携带。前两次握手不能携带数据。
如果前两次握手能够携带数据,那么一旦有人想攻击服务器,那么他只需要在第一次握手中的 SYN 报文中放大量数据,那么服务器势必会消耗更多的时间和内存空间去处理这些数据,增大了服务器被攻击的风险。
第三次握手的时候,客户端已经处于ESTABLISHED状态,并且已经能够确认服务器的接收、发送能力正常,这个时候相对安全了,可以携带数据。
DDOS攻击
三次握手中那一次握手最容易遭受攻击
TCP三次握手在第二阶段容易受到攻击,即syn溢出攻击,如果客户机伪造出大量第一次的syn同步报文,服务端就会依次消耗掉很多资源来保存客户端的信息,并进行确认,实际上确认是会失败的,但失败需要一定的时间,因为服务端会连续多次进行第二次握手确认后才认定失败。那么短时间有大量的syn同步报文涌向服务端,服务端资源可能被耗尽,就可能导致正常的客户端得不到响应而失败。

断开连接的四次挥手

在这里插入图片描述
四次挥手 指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。
由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

  • 第一次挥手:Client发送一个FIN,ACK,确认号和序号,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
  • 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认号为对方序号+1,Server进入CLOSE_WAIT状态。
  • 第三次挥手:Server发送一个FIN和ACK,序号用对方的确认号,确认号为对方序号+1,关闭Server到Client的数据传送,Server进入LAST_ACK状态。
  • 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认号为对方序号+1,Server进入CLOSED状态,完成四次挥手。

上面是一方主动关闭,另一方被动关闭的情况,实际中还会出现同时发起主动关闭的情况。
为什么是四次挥手而不是三次
因为服务端在接收到FIN, 往往不会立即返回FIN, 必须等到服务端所有的报文都发送完毕了,才能发FIN。因此先发一个ACK表示已经收到客户端的FIN,延迟一段时间才发FIN。这就造成了四次挥手。
如果是三次挥手会有什么问题
等于说服务端将ACK和FIN的发送合并为一次挥手,这个时候如果还有很多数据没有传输完成的话那么客户端就不知道自己的FIN是否到了服务端,那么他就会一直发送FIN。

;