Fe7224a497232a28a3c2a2a019ef8e70
说人话的 HTTPS 协议简述——揭秘 Handshake 过程

HTTPS Handshake

上一篇重点是介绍了一些密码学背景和TLS协议的基础架构。本文将重点介绍秘钥交换部分——Handshake。

Handshake做了啥?

在介绍Handshake流程之前,先做一下主要内容的概述,Handshake主要做了以下一些事:

  • 密钥交换
    • 建立共享密钥材料并选择加密参数(此阶段后的所有内容都已加密)
  • 确认服务器参数:
    • 建立其他握手参数(客户端是否认证,应用层协议支持等)。
  • 认证:
    • 验证服务器(并且可选地客户端),并提供密钥确认和握手完整性。

结合以上几点内容看下面的部分,会更加清晰一些。

Handshake流程 (经典2-RTT RSA 单向认证)

第一步:

客户端生成第一个随机数 cRandom,并且发送客户端支持的加密方法给服务端(一般翻译为加密套件),这个过程是明文的。

第二步

Server缓存cRandom,生成第二个随机数sRandom,并且按照客户端支持的加密套件跟服务器支持的加密方法做对比,确认出具体的加密手段。并将sRandom和服务器证书一起下发给客户端。证书主要包含的是公钥串。此处其实也是明文。

第三步

客户端收到证书后,根据证书链去验证服务端证书合法性,并生成第三个随机数Premaster Secret。
由于此时已经有服务器证书了,所以会先用公钥对Premaster Secret做非对称加密。然后传输已经加密了的Premaster Secret。

需要知道的是,此处是RSA的交换过程,如果是DH协商的过程,本身Premaster Secret是不传输的,传递的只有生成Premaster Secret的DH公钥(回顾上一章)。

这一步之后,客户端就开始用三个随机数,基于前两个Hello协商的对称加密方式。开始生成Record阶段使用的对称加密秘钥组了。

第四步

服务端用证书私钥解密,还原客户端发的Premaster Secret,并且向客户端发送finish的ack。至此其实是4次握手都完成了。客户端和服务端用同样的三个随机数,生成同样的Session key。

至此其实Handshake大致过程就已经完成了,但这就结束了吗?

还远着呢!!!


总结几个要点

  1. 交换的3个随机数:Client Random , Server Random, Premaster secret
  2. 不交换的2个随机数:Master Secret, Session Key
  3. 2-RTT:第一个rtt是 ClientHello/ServerHello,约定不同加密手段;第二个rtt是ClientKeyExchange/ServerKeyExchange,根据约定交换秘钥。
  4. 单向认证证书:客户端确保服务端合法,服务端不管客户端

从上述过程可以看出:传统的RSA交换秘钥的算法,保密性严重依赖服务器公钥加密的Premaster Secret,虽然理论上而言,服务器证书的公钥足够长的话,这个传输过程可以被认为是安全的。

另外,一般来说服务器私钥不会保存在CDN。在实际生产环境下,服务器证书私钥是一个极为敏感的保密信息,并不能交给CDN服务商去保存,会单独开辟一个加密服务器。所以最后一步解密PremasterSecret,一般都是CDN向加密服务器做请求。见下图红框部分。

几个疑问

  1. Premaster Secret 有什么必要?
  2. Master Secret 又是啥?
  3. Session Key 怎么计算出来的?

Premaster Secret的必要性

其实需要PremasterSecret,主要是由于TLS协议中,证书是静态的,因此十分有必要引入一种随机因子,保证协商处理的秘钥的随机性。一旦不够随机,秘钥就有可能“被预测”,进而引发攻击(实际上早期SSL协议期间发生过类似事故)。

但是问题是,TLS协议从设计上考虑,并不真正相信每个主机都能生成完全随机的随机数。所以需要cRandom + sRandom + PremasterSecret三个随机数来保证最终秘钥的随机性。

Premaster Secret长度取决于前期加密算法协商的选择,并不是固定的。

对Premaster的理解是各种中文资料里出错较多的地方。各种中文资料中,基本都说是Premaster随机数直接用于后续的对称加密,然而并不准确。不知道为何都这样说。

Master Secret又是啥?

从Premaster Secret这个命名不难发现,有Premaster就一定有一个Master Secret,而这一部分基本上在我能找到的中文资料里都少有提及,如果想看完整的原始定义,建议翻阅RFC5246协议。

上文已经提到,Premaster Secret其实长度并不固定。从便利性考虑,对应不同的加密套件,使用固定长度的随机数做衍生会方便很多。所以有固定长度48位的MasterSecret,生成方法如下:

master_secret = PRF(pre_master_secret, "master secret",
                     cRandom + sRandom)
[0..47];

其中PRF全称是Pseudo-random function,即伪随机数方法。

top Created with Sketch.