基于RSA的TLS握手流程

“我正在参加「掘金·启航计划」”

❤️SSL/TLS专栏导航页❤️


@[TOC]


3.2 基于RSA的TLS握手流程

先看看基于RSA进行密钥配送的TLS握手报文如下: image-20210913231141672

TLS四次握手的报文及其主要内容如下:

image-20210913231006611 下面详细介绍握手阶段的关键报文。

3.2.1 TLS第一次握手

image-20210914222508464 TLS握手首先以客户端发送的:Client Hello报文作为协商的开始。 报文内最容主要包含:TLS版本号,随机数(Client Random),密码套件列表,以及sessionID

TLS版本号:用来确定当前TLS采用的版本,目前有TLS1.0, TLS1.1, TLS1.2,TLS1.3, 各个版本之间并不兼容。

ClientRandom:用于密钥的制作。

密码套件列表:将本端支持的密码套件全部发给服务端,服务端从中挑选一个最安全的密码套件返回客户端。

SessionID:用来表示客户端是否想复用先前存在的session。如果不复用,则此字段为0;如果想要复用,则此字段为想要复用的sessionID。是否复用由服务端确定。

3.2.2 TLS第二次握手

image-20210914224100831

第二次握手报文为服务端的响应报文:Server Hello。 实际上,ServerHello载荷只是服务端响应的一部分,在基于RSA的TLS握手流程中,服务端在第二次握手报文中包括:Server Hello, Certificate, ServerHelloDone共计三个报文。只是在介绍时习惯将其称之为ServerHello。

ServerHello : 是对ClientHello报文中的载荷的协商确认的结果。包括:TLS版本号,随机数(Server Random), SerssionID, 加密套件。 关于这四个参数在ClientHello中已经做了简单介绍,这里不再赘述。

这里再说一下加密套件(CipherSuite)的格式:

TLS——密钥交换算法——签名算法——WITH——加密算法——摘要算法

其中密钥交换算法和签名算法可以合二为一。

上图中服务端选择的算法套件是:TLS_RSA_WITH_AES_256_GCM_SHA384 (0xc030), 它的意思是:

  • 密钥交换算法采用:RSA
  • 签名算法采用:RSA
  • 加密算法采用:AES对称算法,密钥长度为256bit, 模式为:GCM。
  • 摘要算法采用:SHA284

经过Client Hello和Server Hello的交互,客户端和服务端已经交换了各自的随机数(ServerRandom, ClientRandom),此外就TLS版本和加密套件达成一致。

image-20210916001522748 之后服务端发送Certificate证书载荷。证书在客户端有两个作用:

1它是客户端用来验证服务端的身份,如果验证通过则继续后续协商;如果验证不通过则会给客户端发送一条“Bad certificate”的告警消息。在大多数HTTPS实现中,这个证书校验功能可以关闭,此时便不会对服务端证书进行任何校验;

2用于对PreMasterKey的加密,从而完成PMK的传送。这也是两种TLS握手流程的最大区别。

最后服务端发送一个ServerHelloDone载荷,表明服务端的响应已经发送完毕,客户端可以进行后续处理操作了。

3.2.3 TLS第三次握手

image-20210914223915182

客户端收到服务端发送的第二个报文**(ServerHello, Certificate, ServerHelloDone)后,首先检查ServerHello中的协商结果是否ClientHello中支持的;之后通过校验服务端证书来确定服务端身份;然后生成一个随机数PreMasterKey**,使用服务端证书中的公钥进行加密,将加密后的密文通过ClientKeyExchange载荷发送给服务端;

目前客户端已经拥有ClientRandom, ServerRandom, PreMasterKey,以及协商的加密套件。通过这些材料计算出主密钥**(MasterKey)**,然后在依次从主密钥中生成以下四把密钥:

client_write_MAC_secret[SecurityParameters.hash_size]
server_write_MAC_secret[SecurityParameters.hash_size]
client_write_key[SecurityParameters.key_material_length]
server_write_key[SecurityParameters.key_material_length]
  • 主密钥计算公式:

master_secret = PRF(PreMasterKey, "master secret", ClientRandom + ServerRandom)

  • 四把密钥计算公式:

key_block = PRF(master_secret, "key expansion", ServerRandom + ClientRandom);

上面的四把密钥按长度从key_block中截取即可。

计算完毕密钥后,发送ChangeCipherSpec载荷,通知服务端以后发送的报文全部使用新协商的安全参数进行加密。

最后对服务端进行测试,确定是否可以正常解密密文。对方才的握手报文计算摘要,然后再对摘要信息进行加密,组成EncryptedHandshakeMessage载荷发送给服务端。

3.2.4 TLS第四次握手

image-20210914232944420

第四次握手报文与第三次握手比较类似。服务端收到客户端发送的第三个报文**(ClientKeyExchange, ChangeCipherSpec, EncryptedHandshakeMessage)后,并结合前两个报文交互的ClientRandom, ServerRandom**,计算出主密钥,进而几乎算所有的加解密密钥。

收到ChangeCIpherSpec后,使用新协商的安全参数处理后续的所有报文。并发送自己的ChangeCipherSpec报文。

解密EncryptedHandkeMessage。解密成功后,将计算自己的所有握手阶段报文的摘要,然后加密组成EncryptedHandshakeMesssage发送给客户端。

客户端收到编程安全参数,然后解密验证报文。

至此,双方的TLS握手便顺利完成。从此以后可以发送应用层数据,这部分数据便会经过TLS的加密保护。

猜你喜欢

转载自juejin.im/post/7111723291857846280