详解TLS两种握手流程

时间:2023-02-11 13:57:06

握手协议使用若干个报文,它们为服务器认证客户端,为客户端认证服务器,协商加密和散列算法,生成用于数据交换的密码的密钥。握手流程分为两种情况,一种是初始建立会话的完全握手流程,另一种是重用会话的简单流程。

1、完全握手流程

TLS客户端与服务器之间完成握手协议,实现安全连接,需要4个阶段。

详解TLS两种握手流程

*表示可选或视情而定

(1)第一阶段:客户端与服务器之间建立安全增强能力

客户端发送一个ClientHello报文,然后等待服务器的响应,服务器必须响应一个ServerHello报文,否则将会导致一个致命错误,连接将失败。ClientHello和ServerHello报文用于客户端与服务器之间建立安全增强能力,生成安全参数。

ClientHello和ServerHello建立的属性包括协议版本、会话(Session ID)、密码组和压缩方法。客户端提交的ClientHello所包含的密码组(Cipher Suite)是客户支持的密码算法列表(按优先级降序排列),压缩方法是客户支持的压缩方法列表。服务器发送ServerHello时,协议版本是客户建议的低版本以及服务器支持的最高版本,密码组是从客户端建议的密码算法中选定的一种算法,压缩方法是从客户支持的压缩方法中选择的一种算法。

ClientHello和ServerHello还要产生和交换两个随机数:ClientHello.random和ServerHello.random。随机数是32位时间戳加上28字节随机序列。

(2)第二阶段:服务器认证

发送ServerHello报文之后,服务器需要对自己认证,服务器可以发送它的证书和公钥,也可以请求客户端的证书。具体有以下几种情况。

  • 如果自己要被认证的话,服务器发送自己的证书(Certificate)。Certificate 报文包含一个X.509证书,或者一条证书链。除了匿名DH之外的密钥交换方法都需要发送Certificate报文。
  • 服务器发送ServerKeyExchange(服务器密钥交换)报文(如果要求这样做)。例如,服务器没有自己的证书,或者证书仅用于签名。ServerKeyExchange报文包含签名,被签名的内容包括两个随机数以及服务器参数。
  • 非匿名服务器可以向客户端发送CertificateRequest报文请求一个客户端证书,该报文包含整数类型和CA。服务器已被认证,如果对所选的密码组是合适的,它也可能要求客户端发送客户端证书。
  • 服务器发送ServerHelloDone报文,指示握手的Hello阶段完成,然后等待客户端应答。

(3)第三阶段:客户端认证与密钥交换

客户端收到ServerHelloDone报文后,根据需要检查服务器提供的证书,并判断ServerHelloDone的参数是否可以接受,如果都没有问题,发送一个或多个报文给服务器。

如果服务器请求证书,则客户端必须首先发送一个Certificate报文。但是客户端实在没有证书,就发送一个No certificate警告消息。

客户端接着发送ClientKeyExchange(客户端密钥交换)报文,其内容取决于ClientHello和ServerHello之间协商选择的公钥算法。

如果客户端发送了一个具有签名能力的证书,还应发送一个CertificateVerify报文以显式验证该证书。此报文包含一个签名,对从第1条报文以来的所有握手报文的HMAC值用主密钥进行签名。HMAC是Hash-based Message Authentication Code的简称,是一种与密钥相关的散列计算消息认证码。HMAC运算利用散列算法,以一个密钥和一个报文作为输入,生成一个报文摘要作为输出。

(4)第四阶段:建立密码规约

最后客户端和服务器发送报文建立密码规约,允许它们使用这些密钥和参数。

客户端发送一个ChangeCipherSpec(改变密码规约)报文,将挂起的密码规约复制到当前的密码规约中。紧接着客户端立即用新的算法、密钥和密文加密发送一个Finished(已完成)报文,这个报文可以检查密钥交换和认证过程是否已经成功,其中包括一个校验值,对所有握手以来的报文进行校验。

作为回应,服务器同样发送ChangeCipherSpec和Finished报文。服务器发送自己的ChangeCipherSpec,将挂起的密码规约改为当前密码规约,发送使用新的密码规约的Finished报文。

至此,握手过程完成,客户端和服务器可以开始交换应用数据(Application Data)。

2、简单握手流程

客户端和服务器决定重建以前的会话或者复制一个已经存在的会话(而不是重新协商新安全参数),也就是重用已有的TLS会话,握手流程就简化了。

详解TLS两种握手流程

与上述完全握手相比,简单握手省略了第二、三两个阶段。

客户端使用含有要重用的会话的会话ID参数发送ClientHello报文。服务器随后检查是否匹配其会话缓存。如果发现匹配,而且服务器希望在指定的会话状态下重建连接,将发送含有同一会话ID的ServerHello报文。如果服务器没有发现匹配的会话ID,将产生一个新的会话ID,客户端和服务器将开始一个完全的TLS握手过程。

紧接着客户端和服务器都必须发送ChangeCipherSpec(改变密码规约)报文,并直接发送Finished报文。

一旦重建会话完成,客户端和服务器就可以交换应用数据。