HTTPS协议详解(四):TLS/SSL握手过程

一、握手与密钥协商过程

基于RSA握手和密钥交换的客户端验证服务器为示例详解TLS/SSL握手过程nginx

 

再看一张手绘时序图算法

(1).client_hello
    客户端发起请求,以明文传输请求信息,包含版本信息,加密套件候选列表,压缩算法候选列表,随机数,扩展字段等信息,相关信息以下:
    • 支持的最高TSL协议版本version,从低到高依次 SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2,当前基本再也不使用低于 TLSv1 的版本;
    • 客户端支持的加密套件 cipher suites 列表, 每一个加密套件对应前面 TLS 原理中的四个功能的组合:认证算法 Au (身份验证)、密钥交换算法 KeyExchange(密钥协商)、对称加密算法 Enc (信息加密)和信息摘要 Mac(完整性校验);
    • 支持的压缩算法 compression methods 列表,用于后续的信息压缩传输;
    • 随机数 random_C,用于后续的密钥的生成;
    • 扩展字段 extensions,支持协议与算法的相关参数以及其它辅助信息等,常见的 SNI 就属于扩展字段,后续单独讨论该字段做用。
(2).server_hello+server_certificate+sever_hello_done
    • server_hello, 服务端返回协商的信息结果,包括选择使用的协议版本 version,选择的加密套件 cipher suite,选择的压缩算法 compression method、随机数 random_S 等,其中随机数用于后续的密钥协商;
    • server_certificates, 服务器端配置对应的证书链,用于身份验证与密钥交换;
    • server_hello_done,通知客户端 server_hello 信息发送结束;windows

(3).证书校验
    客户端验证证书的合法性,若是验证经过才会进行后续通讯,不然根据错误状况不一样作出提示和操做,合法性验证包括以下:
    • [证书链]的可信性 trusted certificate path,方法如前文所述;
    • 证书是否吊销 revocation,有两类方式离线 CRL 与在线 OCSP,不一样的客户端行为会不一样;
    • 有效期 expiry date,证书是否在有效时间范围;
    • 域名 domain,核查证书域名是否与当前的访问域名匹配,匹配规则后续分析;
(4).client_key_exchange+change_cipher_spec+encrypted_handshake_message
    (a) client_key_exchange,合法性验证经过以后,客户端计算产生随机数字 Pre-master,并用证书公钥加密,发送给服务器;
    (b) 此时客户端已经获取所有的计算协商密钥须要的信息:两个明文随机数 random_C 和 random_S 与本身计算产生的 Pre-master,计算获得协商密钥;
    enc_key=Fuc(random_C, random_S, Pre-Master)
    (c) change_cipher_spec,客户端通知服务器后续的通讯都采用协商的通讯密钥和加密算法进行加密通讯;
    (d) encrypted_handshake_message,结合以前全部通讯参数的 hash 值与其它相关信息生成一段数据,采用协商密钥 session secret 与算法进行加密,而后发送给服务器用于数据与握手验证;
(5).change_cipher_spec+encrypted_handshake_message
    (a) 服务器用私钥解密加密的 Pre-master 数据,基于以前交换的两个明文随机数 random_C 和 random_S,计算获得协商密钥:enc_key=Fuc(random_C, random_S, Pre-Master);
    (b) 计算以前全部接收信息的 hash 值,而后解密客户端发送的 encrypted_handshake_message,验证数据和密钥正确性;
    (c) change_cipher_spec, 验证经过以后,服务器一样发送 change_cipher_spec 以告知客户端后续的通讯都采用协商的密钥与算法进行加密通讯;
    (d) encrypted_handshake_message, 服务器也结合全部当前的通讯参数信息生成一段数据并采用协商密钥 session secret 与算法加密并发送到客户端;缓存

(6).握手结束
    客户端计算全部接收信息的 hash 值,并采用协商密钥解密 encrypted_handshake_message,验证服务器发送的数据和密钥,验证经过则握手完成;
(7).加密通讯
    开始使用协商密钥与算法进行加密通讯。
注意:
    (a) 服务器也能够要求验证客户端,即双向认证,能够在过程2要发送 client_certificate_request 信息,客户端在过程4中先发送 client_certificate与certificate_verify_message 信息,证书的验证方式基本相同,certificate_verify_message 是采用client的私钥加密的一段基于已经协商的通讯信息获得数据,服务器能够采用对应的公钥解密并验证;
    (b) 根据使用的密钥交换算法的不一样,如 ECC 等,协商细节略有不一样,整体类似;
    (c) sever key exchange 的做用是 server certificate 没有携带足够的信息时,发送给客户端以计算 pre-master,如基于 DH 的证书,公钥不被证书中包含,须要单独发送;
    (d) change cipher spec 实际可用于通知对端改版当前使用的加密通讯方式,当前没有深刻解析;
    (e) alter message 用于指明在握手或通讯过程当中的状态改变或错误信息,通常告警信息触发条件是链接关闭,收到不合法的信息,信息解密失败,用户取消操做等,收到告警信息以后,通讯会被断开或者由接收方决定是否断开链接。安全

 

二、会话缓存握手过程

    为了加快创建握手的速度,减小协议带来的性能下降和资源消耗(具体分析在后文),TLS 协议有两类会话缓存机制:会话标识 session ID 与会话记录 session ticket。
    session ID 由服务器端支持,协议中的标准字段,所以基本全部服务器都支持,服务器端保存会话ID以及协商的通讯信息,Nginx 中1M 内存约能够保存4000个 session ID 机器相关信息,占用服务器资源较多;
    session ticket 须要服务器和客户端都支持,属于一个扩展字段,支持范围约60%(无可靠统计与来源),将协商的通讯信息加密以后发送给客户端保存,密钥只有服务器知道,占用服务器资源不多。
    两者对比,主要是保存协商信息的位置与方式不一样,相似与 http 中的 session 与 cookie。
    两者都存在的状况下,(nginx 实现)优先使用 session_ticket。
    握手过程以下图:服务器

 

注意:虽然握手过程有1.5个来回,可是最后客户端向服务器发送的第一条应用数据不须要等待服务器返回的信息,所以握手延时是1*RTT。
(1).会话标识 session ID
    (a) 若是客户端和服务器之间曾经创建了链接,服务器会在握手成功后返回 session ID,并保存对应的通讯参数在服务器中;
    (b) 若是客户端再次须要和该服务器创建链接,则在 client_hello 中 session ID 中携带记录的信息,发送给服务器;
    (c) 服务器根据收到的 session ID 检索缓存记录,若是没有检索到货缓存过时,则按照正常的握手过程进行;
    (d) 若是检索到对应的缓存记录,则返回 change_cipher_spec 与 encrypted_handshake_message 信息,两个信息做用相似,encrypted_handshake_message 是到当前的通讯参数与 master_secret的hash 值;
    (f) 若是客户端可以验证经过服务器加密数据,则客户端一样发送 change_cipher_spec 与 encrypted_handshake_message 信息;
    (g) 服务器验证数据经过,则握手创建成功,开始进行正常的加密数据通讯。
(2).会话记录 session ticket
    (a) 若是客户端和服务器之间曾经创建了链接,服务器会在 new_session_ticket 数据中携带加密的 session_ticket 信息,客户端保存;
    (b) 若是客户端再次须要和该服务器创建链接,则在 client_hello 中扩展字段 session_ticket 中携带加密信息,一块儿发送给服务器;
    (c) 服务器解密 sesssion_ticket 数据,若是可以解密失败,则按照正常的握手过程进行;
    (d) 若是解密成功,则返回 change_cipher_spec 与 encrypted_handshake_message 信息,两个信息做用与 session ID 中相似;
    (f)若是客户端可以验证经过服务器加密数据,则客户端一样发送 change_cipher_spec与encrypted_handshake_message 信息;
    (g) 服务器验证数据经过,则握手创建成功,开始进行正常的加密数据通讯。cookie

 

三、重建链接

    重建链接 renegotiation 即放弃正在使用的 TLS 链接,重新进行身份认证和密钥协商的过程,特色是不须要断开当前的数据传输就能够从新身份认证、更新密钥或算法,所以服务器端存储和缓存的信息均可以保持。客户端和服务器都可以发起重建链接的过程,当前 windows 2000 & XP 与 SSL 2.0不支持。
(1).服务器重建链接session

 

    服务器端重建链接通常状况是客户端访问受保护的数据时发生。基本过程以下:
    (a) 客户端和服务器之间创建了有效 TLS 链接并通讯;
    (b) 客户端访问受保护的信息;
    (c) 服务器端返回 hello_request 信息;
    (d) 客户端收到 hello_request 信息以后发送 client_hello 信息,开始从新创建链接。
(2).客户端重建链接并发

客户端重建链接通常是为了更新通讯密钥。
    (a) 客户端和服务器之间创建了有效 TLS 链接并通讯;
    (b) 客户端须要更新密钥,主动发出 client_hello 信息;
    (c) 服务器端收到 client_hello 信息以后没法当即识别出该信息非应用数据,所以会提交给下一步处理,处理完以后会返回通知该信息为要求重建链接;
    (d) 在肯定重建链接以前,服务器不会当即中止向客户端发送数据,可能刚好同时或有缓存数据须要发送给客户端,可是客户端不会再发送任何信息给服务器;
    (e) 服务器识别出重建链接请求以后,发送 server_hello 信息至客户端;
    (f) 客户端也一样没法当即判断出该信息非应用数据,一样提交给下一步处理,处理以后会返回通知该信息为要求重建链接;
    (g) 客户端和服务器开始新的重建链接的过程。dom

四、密钥计算

上节提到了两个明文传输的随机数 random_C 和 random_S 与经过加密在服务器和客户端之间交换的 Pre-master,三个参数做为密钥协商的基础。本节讨论说明密钥协商的基本计算过程以及通讯过程当中的密钥使用。
(1).计算 Key
涉及参数 random client 和 random server, Pre-master, Master secret, key material, 计算密钥时,服务器和客户端都具备这些基本信息,交换方式在上节中有说明,计算流程以下:

 

    (a) 客户端采用 RSA 或 Diffie-Hellman 等加密算法生成 Pre-master;
    (b) Pre-master 结合 random client 和 random server 两个随机数经过 PseudoRandomFunction(PRF)计算获得 Master secret;
    (c) Master secret 结合 random client 和 random server 两个随机数经过迭代计算获得 Key material;
如下为一些重要的记录,能够解决部分爱深刻研究朋友的疑惑,copy的材料,分享给你们:
    (a) PreMaster secret 前两个字节是 TLS 的版本号,这是一个比较重要的用来核对握手数据的版本号,由于在 Client Hello 阶段,客户端会发送一份加密套件列表和当前支持的 SSL/TLS 的版本号给服务端,并且是使用明文传送的,若是握手的数据包被破解以后,攻击者颇有可能串改数据包,选择一个安全性较低的加密套件和版本给服务端,从而对数据进行破解。因此,服务端须要对密文中解密出来对的 PreMaster 版本号跟以前 Client Hello 阶段的版本号进行对比,若是版本号变低,则说明被串改,则当即中止发送任何消息。(copy)
    (b) 无论是客户端仍是服务器,都须要随机数,这样生成的密钥才不会每次都同样。因为 SSL 协议中证书是静态的,所以十分有必要引入一种随机因素来保证协商出来的密钥的随机性。
    对于 RSA 密钥交换算法来讲,pre-master-key 自己就是一个随机数,再加上 hello 消息中的随机,三个随机数经过一个密钥导出器最终导出一个对称密钥。
    pre master 的存在在于 SSL 协议不信任每一个主机都能产生彻底随机的随机数,若是随机数不随机,那么 pre master secret 就有可能被猜出来,那么仅适用 pre master secret 做为密钥就不合适了,所以必须引入新的随机因素,那么客户端和服务器加上 pre master secret 三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能彻底不随机,但是三个伪随机就十分接近随机了,每增长一个自由度,随机性增长的可不是一。
(2).密钥使用
    Key 通过12轮迭代计算会获取到12个 hash 值,分组成为6个元素,列表以下:

    (a) mac key、encryption key 和 IV 是一组加密元素,分别被客户端和服务器使用,可是这两组元素都被两边同时获取;
    (b) 客户端使用 client 组元素加密数据,服务器使用 client 元素解密;服务器使用 server 元素加密,client 使用 server 元素解密;
    (c) 双向通讯的不一样方向使用的密钥不一样,破解通讯至少须要破解两次;
    (d) encryption key 用于对称加密数据;
    (e) IV 做为不少加密算法的初始化向量使用,具体能够研究对称加密算法;
    (f) Mac key 用于数据的完整性校验;
(3).数据加密通讯过程
    (a) 对应用层数据进行分片成合适的 block;
    (b) 为分片数据编号,防止重放攻击;
    (c) 使用协商的压缩算法压缩数据;
    (d) 计算 MAC 值和压缩数据组成传输数据;
    (e) 使用 client encryption key 加密数据,发送给服务器 server;
    (f) server 收到数据以后使用 client encrytion key 解密,校验数据,解压缩数据,从新组装。
注:MAC值的计算包括两个 Hash 值:client Mac key 和 Hash (编号、包类型、长度、压缩数据)。

 

五、抓包分析

关于抓包再也不详细分析,按照前面的分析,基本的状况都可以匹配,根据日常定位问题的过程,我的提些认为须要注意的地方:    (1).抓包 HTTP 通讯,可以清晰的看到通讯的头部和信息的明文,可是 HTTPS 是加密通讯,没法看到 HTTP 协议的相关头部和数据的明文信息,    (2).抓包 HTTPS 通讯主要包括三个过程:TCP 创建链接、TLS 握手、TLS 加密通讯,主要分析 HTTPS 通讯的握手创建和状态等信息。    (3).client_hello根据 version 信息可以知道客户端支持的最高的协议版本号,若是是 SSL 3.0 或 TLS 1.0 等低版本协议,很是注意可能由于版本低引发一些握手失败的状况;根据 extension 字段中的 server_name 字段判断是否支持SNI,存在则支持,不然不支持,对于定位握手失败或证书返回错误很是有用;会话标识 session ID 是标准协议部分,若是没有创建过链接则对应值为空,不为空则说明以前创建过对应的链接并缓存;会话记录 session ticke t是扩展协议部分,存在该字段说明协议支持 sesssion ticket,不然不支持,存在且值为空,说明以前未创建并缓存链接,存在且值不为空,说明有缓存链接。    (4).server_hello    根据 TLS version 字段可以推测出服务器支持的协议的最高版本,版本不一样可能形成握手失败;    基于 cipher_suite 信息判断出服务器优先支持的加密协议;    (5).ceritficate    服务器配置并返回的证书链,根据证书信息并于服务器配置文件对比,判断请求与指望是否一致,若是不一致,是否返回的默认证书。    (6).alert    告警信息 alert 会说明创建链接失败的缘由即告警类型,对于定位问题很是重要

相关文章
相关标签/搜索