SSL/TLS 协议运行机制概述(一)
SSL/TLS 发展史
- 1994年,NetScape 设计了SSL协议(Secure Sockets Layer) 1.0,未正式发布
- 1995年,NetScape 发布 SSL 2.0
- 1996年,发布 SSL 3.0
- 1999年,IETF标准化了SSL协议,更名为 TLS(Transport Layer Security),发布TLS 1.0
- 2006年4月,IETF 工作组发布了 TLS 1.1
- 2008年8月,IETF 工作组发布了 TLS 1.2
- 2018年8月,TLS 1.3正式发布
作用
不使用 SSL/TLS 的 HTTP 通信,所有信息明文传播,存在如下风险:
- 窃听风险(eavesdropping):第三方可以获知通信内容。
- 篡改风险(tampering):第三方可以修改通信内容。
- 冒充风险(pretending):第三方可以冒充他人身份参与通信。
SSL/TLS 协议是为了解决这三大风险而设计的,希望达到:
- 所有信息都是加密传播,第三方无法窃听。
- 具有校验机制,一旦被篡改,通信双方会立刻发现。
- 配备身份证书,防止身份被冒充。
SSL/TLS 握手
基于 RSA 的 TLS 1.2 握手过程
每个 TLS 握手涉及一系列步骤,这些步骤完成三个主要任务:
- 交换加密功能
- 验证 SSL 证书
- 交换/生成会话密钥
下面是TLS 1.2握手的步骤(使用RSA,在后面还有一个Diffie-Hellman tls1.2握手的例子)
- 第一条消息称为 “ClientHello”。这条消息列出了客户端的功能,以便服务器可以选择两者用来通信的密码套件。它还包括一个随机选取的大素数,称为“client random”。
- 服务器用 “SeverHello” 消息响应。在此消息中,它告诉客户端它从提供的列表中选择了哪些连接参数,并返回自己随机选择的素数,称为 “server random”。如果客户端和服务器不共享任何功能,则连接将失败终止。
- 在 “Certification” 消息中,服务器将其 SSL 证书链(包括其叶证书和中间证书)发送到客户端。为了向连接提供身份验证,一个 SSL 证书由 CA 签名,这允许客户端验证该证书是否合法。收到证书后,客户端将执行多个检查以验证证书。这包括检查证书的数字签名、验证证书链,以及检查证书数据的任何其他潜在问题(过期的证书、错误的域名等)。客户端还将确保服务器拥有证书的私钥。这是在密钥交换/生成过程中完成的。
- 这是一条可选消息,仅对于某些需要服务器提供额外数据的密钥交换方法(Diffie-Hellman)才需要。
- “Server Hello Done” 消息告诉客户端它已经发送了所有消息。
- 客户端为生成会话密钥(session key)。此步骤的具体内容取决于在初始 “Hello” 消息中确定的密钥交换方法。在本例中,我们研究的是 RSA,因此客户端将生成一个称为 pre-master secret 的随机字符串,然后使用服务器的公钥对其进行加密并传输它。
- “Change Cipher Spec” 消息让另一方知道它已经生成了会话密钥,并将切换到加密通信。
- “Finished” 消息以指示在客户端完成握手。完成的消息是加密的,并且是受会话密钥保护的第一个数据。消息包含数据(MAC),允许各方确保握手未被篡改。
- 它解密 pre-master secret 并计算会话密钥。然后它发送 “Change Cipher Spec” 消息以指示它正在切换到加密通信。
- 服务器使用刚刚生成的对称的会话密钥发送其 “Finished” 消息,它还执行相同的校验和以验证握手的完整性。
在这些步骤之后,TLS 握手就完成了。双方现在都有一个会话密钥,并将开始与加密和身份验证的连接通信。
RSA 密钥交换
- 客户端和服务器交换两个素数(x 和 y),称为随机数。
- 客户端生成一个预主密钥(pre-master secret)(a),然后使用服务器的公钥对其进行加密并将其发送到服务器。
- 服务器使用相应的私钥解密pre-master secret,双方现在都有三个输入,并将它们与一些伪随机函数(PRFs)混合以生成主密钥(master secret)。
- 双方将更多的 PRFs 与 master secret 混合,并派生出匹配的会话密钥
Diffie-Hellman 密钥交换
DH 过程:
- 客户端和服务器交换两个素数(x 和 y),称为随机数。
- 一方选择一个名为 pre-master secret(a)的密码并计算: (x^a) mod y ,然后将结果(A)发送给另一方。
- 另一方做同样的事情,选择自己的 pre-master secret(b)并计算 (x^b) mod y,然后将其值(B)发回。
- 双方通过获取给定值并重复操作来完成此部分。一个计算 (B^a) mod y,另一个计算 (A^b) mod y。
如上根据模指数性质推导,它表明每一方将得到相同的值,这是在连接期间用于对称加密的密钥。
基于 DH 的 TLS 1.2 握手过程
- 与 RSA 一样,客户机以一条 “ClientHello” 消息开始,该消息包括一个密码套件列表以及 client random。
- 服务器用它自己的 “ServerHello” 消息来响应,该消息包括它选择的密码套件和它的 server random。
- 服务器发送其 SSL 证书,就像 RSA TLS 握手一样,客户端将运行一系列检查来验证证书是否有效,但是由于 DH 本身无法验证服务器,因此需要一个附加机制。
- 为了提供身份验证,服务器接受客户端和服务器随机数以及用于计算会话密钥的 DH 参数,并使用其私钥对它们进行加密。这起到了数字签名的作用,客户机将使用公钥来验证签名(并且服务器是密钥对的合法所有者),并使用自己的 DH参数进行响应。
- 服务器以 “Server Hello Done” 消息结束这次往返。
- 与 RSA 不同,客户端不需要使用非对称加密将 pre-master secure 发送到服务器,而客户端和服务器使用它们先前交换的 DH 参数来获得 pre-master secure。然后,每一个都使用它刚刚计算出来的 pre-master secure 来计算获得会话密钥。
- 客户端发送 “Change Cipher Spec” 消息,通知另一方其切换到加密。
- 客户端发送 “Finished” 消息,表示它已经完成了它的握手工作。
- 同样,服务器发送 “Change Cipher Spec” 消息。
- 握手以服务器 “Finished” 消息结束。
基于 DH 相对 RSA 的优势
DHE 是完美前向保密(Perfect Forward Secrecy)的,而 RSA 不是。
回溯破解
从技术上讲,攻击者如果能够对通讯双方进行嗅探,也就能够把通讯双方的传输数据存储下来。如果攻击者比较厉害,能拿到通讯双方的私钥,那就有可能根据私钥推导出会话密钥,从而解密之前存储的历史数据。
攻击者如何拿到私钥?
- 入侵双方的操作系统(搞定了操作系统,自然就能搞定系统中存储的私钥)
- 利用协议设计的漏洞
- 利用协议实现的安全漏洞(比如“心脏滴血漏洞”,有可能会导致私钥泄漏。协议本身没问题,是 OpenSSL 的代码实现出了 bug)
- 通过社会工程学
而 RSA 就容易遭到回溯破解。攻击者事先存储了通讯的密文(历史数据)。由于 RSA 的私钥是稳定的(长期不变)。假设有一天,攻击者拿到了 RSA 的私钥,就可以用这个私钥解密握手过程的密文,从而得到会话密钥(session key),然后用会话密钥解密会话的密文,得到会话的明文。
相比 RSA,DH 和 ECDH(DH 的一个变种) 是抗“回溯破解”的。对于 DH 算法,通讯双方握手需要生成各自的私钥(前面 Diffie-Hellman 密钥交换提到的 a 和 b),然后根据 DH 算法计算得出会话密钥。换句话说,会话密钥依赖于双方的私钥 a 与 b。DH 算法的优势在于——双方的私钥(a & b)是可以动态生成的!
为了对抗“回溯破解”,可以强制要求双方每次都生成随机的私钥。而且每次生成的两个私钥用完就丢弃(销毁)。如此一来,攻击者就难以破解过往的历史数据。DH 算法经过如此改良之后叫做 DHE(追加的字母 E 表示 ephemeral)。
与 DH 类似,ECDH 也可以做类似的改良,变成 ECDHE,以对抗“回溯破解”。
能够对抗“回溯破解”的密钥交换算法,被称为“完美前向保密(Perfect Forward Secrecy)”
一些问题
(1)握手过程是如何保证公钥不被篡改?(如中间人攻击)
将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。
(2)公钥加密计算量太大,如何减少耗用的时间?
每一次会话(session),客户端和服务器端都生成一个"会话密钥"(session key),用它来加密信息。由于"会话密钥"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"会话密钥"本身,这样就减少了加密运算的消耗时间。
(3)为什么一定要用三个随机数,来生成"会话密钥"?
"不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于 SSL 协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。
对于RSA密钥交换算法来说,pre-master-key 本身就是一个随机数,再加上 hello 消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。
pre master 的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么 pre master secret 就有可能被猜出来,那么仅适用 pre master secret 作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上 pre master secret 三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。"
参考链接:
http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html
https://www.thesslstore.com/blog/explaining-ssl-handshake/
https://program-think.blogspot.com/2016/09/https-ssl-tls-3.html