无题/TCP和HTTP和HTTPS

Created Wed, 24 Feb 2021 21:49:01 +0800 Modified Wed, 13 Dec 2023 07:03:38 +0000

本文主要介绍一下TCP和HTTP&HTTPS之间的关系

TCP

TCP是传输层上的面向连接的可靠传输协议

三次握手

  1. TCP的连接通过三次握手来完成,第一次握手由客户端发起,客户端设置数据包中SYN字段为1,ACK字段为1并随机选取一个值x作为该数据包的seq发送给服务器并调整当前状态为SYN_SEND
  2. 服务器在接受到来自客户端的SYN=1的数据包后知道要开始建立连接,于是服务器设置SYN字段为1,ACK为1,随机选取一个值y作为该包的seq并设置下一个希望得到的数据包序列号为x+1最后发送给客户端并调整当前转台为SYN_RECIVE
  3. 客户端在收到第二个握手包后可以确定服务端与自己的连接是互通的,于是设置数据包的ACK字段为1,seq为x+1并设置希望下一个来自服务端的数据包的序列号为y+1发送给服务端服务端在接受到第三个握手包后可以确定客户端与自己的连接是互通的,由此可以确保数据的传输

四次挥手

TCP的断开连接可以由客户端或服务端发起,设发起的一方为客户端

  1. 客户端设置数据包的FIN字段为1,假设当前seq为u发送该包之后客户端调整状态为FIN_WAIT1
  2. 服务端在收到FIN的数据包后调整状态为CLOSE_WAIT并设置数据包的ACK为1,ack为u+1,seq为w
  3. 客户端在收到服务端的ACK包后进入FIN_WAIT2状态,持续等待;服务端在发送完ACK包后不会立刻断开连接,而是会等待服务端所有数据全部传输完成之后在向客户端发起第三次挥手,其FIN为1,ACK为1,seq为v,ack为u+1
  4. 客户端在收到该FIN后进入TIME_WAIT状态并向服务端发送ACK=1,seq为u+1,ack=v+1的数据包通知服务端关闭连接,服务端在收到后会立刻关闭连接而客户端则会等待2

如果客户端出现故障会如何

服务端会在与客户端连接之后设置一个计时器,当客户端出现故障,服务端不可能一直等待下去,计时器会在建立时开始及时,通常为2个消失,每一次收到客户端连接之后都会重置计时器。当计时器结束之后服务端可以认为客户端出现故障或不再需要数据,此时就关闭连接

HTTP

HTTP是一种明文传输的超文本传输协议

由于其是明文的因此非常的不安全,由此诞生了HTTPS

HTTPS

HTTPS是建立在HTTP之上的,其在传输过程中加上了一层SSL/TLS用于给文本加密

HTTPS的加密解密同时使用了对称加密和非对称加密,由于非对称加密的性能要比对称加密低,因此HTTPS会在交换对称加密密钥时进行非对称加密传输,防止被中间人猜出。然后再根据得到的密钥文件对要传输的内容进行对称加密

认证问题

在HTTPS中,每一个连接都会在其头部添加数字签名,生成数字签名的密钥由CA发放

服务端报文经过HASH处理后生成摘要信息,摘要信息使用私钥加密生成签名,随同报文一起发送给客户端

客户端接受后将签名提取出来并用公钥进行解密,如果能正确解密则说明该报文是来自服务端的

数据完整性

在解决认证问题后就要解决数据完整性的问题,而这个问题就会使用上述的摘要信息进行完成

客户端在对摘要进行解密后会得到该报文的Hash摘要,客户端只需要通过把报文中的数据提取出来进行相同的Hash操作得到另一份摘要后与前一份进行对比就能判断传输的数据是否完整了

而Hash算法等相关信息都会在证书交换中进行传送

工作流程

  1. Client Hello
    客户端向服务端发送Client Hello消息,该消息包含客户端生成的随机数Random1、客户端支持的加密套件和SSL版本信息等
  2. Server Hello
    服务端向客户端发送Server Hello消息,该消息会从Client Hello中确定一份加密套件,该套件决定了后续加密和生成摘要所需使用的集体算法,除此之外还会生成一个随机数Random2
  3. Certificate
    服务端下发证书给客户端,让客户端验证自己的身份,客户端验证通过后取出公钥
  4. Certificate Verify 客户端收到服务端的证书后先从CA验证证书合法性,提取证书中的公钥并生成随机数Random3,再用刚刚提取的公钥对随机数加密生成PreMasterKey发送给服务端
  5. Client Key Exchange 服务端通过私钥解密得到Random3,此时客户端服务端均包含三个随机数,双方根据之前协定的算法生成一份密钥,在握手结束后的数据传输均使用该密钥进行对称加密
  6. EncryptedHandshakeMessage 客户端将前面的握手消息生成摘要再用协商好的密钥加密发送给服务端,服务端用密钥解密如果能够解出则说明密钥一致
  7. Change Cipher Spec 服务端通知客户端后续消息均使用加密
  8. Encrypted Handshake Message 服务端将握手消息生成摘要加密发送给客户端,客户端接受后解密,成功则说明一致
  9. Application data 此时双方已安全协商密钥,至此后续所有应用层数据都将使用该密钥进行加密后通过TCP进行传输

TLS版本区别

  1. 在1.0和1.1计算Finish报文时,进行的是md5+sha1组合运行而1.2下变成了单次sha1
  2. 在证书校验中,1.0和1.1会对握手信息使用md5+sha1进行摘要运算(对于ECC证书只做SHA1计算),在1.2下验证报文多出两个字节hash_alg和sign_alg,假如加密套件存在SHA384则使用SHA384进行加密

RTT问题

由于HTTPS是建立在HTTP之上的,而HTTP是通过TCP实现的,因此HTTPS的建立也需要经历TCP的3次握手但远远不够

这是因为HTTPS除了需要交换连接信息还需要交换证书文件,保证数据完整性等等内容,这会需要增加连接的数量

实际上HTTPS会比HTTP多7个RTT,首先3个握手RTT,然后跳转HTTPS1个RTT,再TCP连接443端口3个RTT,然后开始完成加密套件的协商和证书身份确认。在浏览器获取到证书后也会验证证书的有效性并获取CA域名,解析CA成功后与CA握手并进行OCSP请求确认证书状态

握手优化

由于HTTPS会比HTTP多很多RTT,因此假如在同一时刻大量请求会导致服务端承受不住因此需要对握手进行优化

  1. Session id
    这个方法的实现放在服务端,在客户端请求服务端后会对客户端生成一个session id,保存与该客户端的协商信息,在后续再收到该客户端连接时可以直接通过session id来获取协商信息直接开始数据传输
  2. Session Ticket
    Session id在负载均衡会出现问题,而Ticket的方法则不会因为他主要是现在客户端需要浏览器支持,ticket是只有服务端知道的安全密钥加密过的会话信息,浏览器在Hello时带上ticket服务端就能成功解密进行快速握手

Certificate Chain

TLS的身份认证是通过证书信任链完成的,浏览器从站点证书开始递归校验父证书,直至出现根证书