今天在拜读过seanlook发表的《SSL/TLS原理详解》后,试图复述一遍该文加深理解。
TLS 加密主要有三个目的:

  1. 客户端和服务器端的身份认证,以保证数据不被劫持
  2. 选择加密算法,加密通讯数据
  3. 维持/校验数据完整性,确保数据未被篡改

TLS/SSL与 HTTP 协议同属应用程序层协议,如图(来源于微软 MSDN)

TLS/SSL 协议由 TLS/SSL Record 和 TLS/SSL Handshake两个协议组成。
在流程上,TLS/SSL Handshake发生在三次握手之后,http 正式通讯协议之前; TLS/SSL Record发生在 HTTP 通讯之间:

本文分为两部分:

  • TLS加密的过程:以拟人化的手法复述 TLS 加密的过程
  • TLS如何定义加密过程的: 将以阅读 TLS 协议为主要内容。

摘要

TLS 约定加密,主要有两个目的:

  • 验证客户端和服务器端的身份:这个是通过 certificate 完成的。
  • 会话密钥:这个 session key 是由每次会话过程中传递的随机数生成的,客户端,服务器端各自保存。

TLS 的约定流程:
设:客户端(小绿人)和服务器端(小蓝人)两信友,在确认了对方可以接到自己的邮件并可以进行回复(三次握手)后开始聊天。

TLS 安全原理:

  • 由于非对称加密的速度比较慢,所以它一般用于密钥交换,双方通过公钥(由 certificate 提供)算法协商出一份密钥,然后通过对称加密来通信;
  • 密钥的生成与协商中每一步提供的随机数相关,只有监听了所有的会话才能得到对应的密钥。
  • 第二步和第三步涉及了certificate 的交换和验证,因此第二步和第三步理论上是安全的,不会泄密的。(?证书不可复制,只可伪造),防止了在约定过程中,要防止因为窃听/劫持,造成最终生成的会话密钥泄露的问题。

作为程序员还要注意的是:

  • certificate 告警(第三步验证证书合法性)的处理导致的安全问题(middle in the middle)。
  • 客户端 certificate 的传输阶段(Cerficate Request)。

TLS加密的过程

TLS 协商加密的主要过程

设:客户端(小绿人)和服务器端(小蓝人)两信友,在确认了对方可以接到自己的邮件并可以进行回复(三次握手)后开始聊天。


然而呢,最近拆信党活动猖獗,为了自己的通信内容不被泄露,双方首先要确定下信件的加密方法。

第一步:客户端say hello to 服务器端(Client Hello)

首先,客户端(小绿人)向服务器端(小蓝人)发出协商加密的请求:


在这个步骤里:
客户端将向服务器端,发送一个加密的请求。
这个请求包括:

  • 客户端使用的通信协议及版本:TLS 1.0
  • 客户端支持的加密算法:非对称算法(RSA、DH)对称加密(DES,RC5);
  • 摘要压缩算法:MD5、SHA
  • 随机数1:客户端的随机数需要跟服务端产生的随机数结合起来产生后面要讲到的 Master Secret,具体参见密钥的生成

第二步:服务器回应(Server Hello)

服务器收到客户端传来的信息后,首先会确定是否支持客户端提供的协议、算法,并确定最终使用的协议,算法。如果服务器不支持客户端提供的算法列表,那么服务器将中断这次会话。
服务器回应不仅仅限于一次发送,也许会通过多次发送来传递全部消息,但是不论几次发送,都会以Server Done 为成功标志。

这些内容主要包括:

  • 证书信息:证书主要用来供客户端验证服务器端的身份,证书的公钥会在后续的机密中用到。
    具体见后续的证书验证

  • Cerficate Request:要求客户端提供证书来证明自己的身份(optional)

  • 服务器端选择的加密通信协议

  • 服务器端选择的公钥加密算法

  • 随机数2:客户端的随机数需要跟服务端产生的随机数结合起来产生后面要讲到的 Master Secret ,具体参见密钥的生成

第三步:客户端校验(Client Verify)

客户端如果接到服务器发过的Cerficate Request,会首先把自己的 certificate 发给服务器端进行验证。
然后,客户端会验证服务器端certificate,具体见后续的证书验证。要注意的是,如果证书校验有异常,客户端会收到一个告警(很多浏览器提供的 https 告警),客户端可以自行选择:通过还是不通过。
最后,客户端会发出协商的最后一次请求。

请求的内容:

  • PreMaster secret:以之前商定的 version+随机数3,采用协商的非对称算法和证书中的公钥加密,具体参见密钥的生成
  • ChangeCipherSpec:一个独立的协议,表示采纳服务器选择的加密组合,后续的通讯信息是经过加密的。
  • Finish信息:使用加密组合的摘要算法将第一步传输的信息生成hash,并且用随机数1、2、3生成的master key+选择的对称加密算法加密(具体参见密钥的生成)。模拟 发起加密后的http request,以验证加密算法可行性。

第四步:服务器结束加密协商(Server Finish)

服务器在接到客户端的信息后,会依次处理:

  1. 解Premaster key:根据手中证书的密钥,解得version(前两位)+随机数3,验证这次会话的 version(防止降维攻击,防止第一步的协商被伪造使得协议版本降低从而降低加密级别);
  2. 切换到解密状态:收到ChangeCipherSpec,采纳以前协商的加密组合。
  3. 用随机数1,2,3解出加密信息,比较验证。模拟解加密后的 http request,验证对方使用的加密算法和自己相同。

服务器端最后发出一次 Finish 标记服务器端也没什么问题了。模拟发起加密后的http reponse,以验证加密算法可行性。
客户端在校验过服务器端的 Finish 信息,确认安全无误后,就可以可是正式的http请求了(当然这是加密了的)。模拟解加密后的 http response,验证对方使用的加密算法和自己相同。

总结

图片和总结来源于《SSL/TLS原理详解》

SSL客户端(也是TCP的客户端)在TCP链接建立之后,发出一个ClientHello来发起握手,这个消息里面包含了自己可实现的算法列表和其它一些需要的消息,SSL的服务器端会回应一个ServerHello,这里面确定了这次通信所需要的算法,然后发过去自己的证书(里面包含了身份和自己的公钥)。Client在收到这个消息后会生成一个秘密消息,用SSL服务器的公钥加密后传过去,SSL服务器端用自己的私钥解密后,会话密钥协商成功,双方可以用同一份会话密钥来通信了。
TLS 加密过程

TLS 安全性的一些防范

middle in the middle攻击

《The End of SSL and SSH?》这篇文章中提到了,成熟的工具如dsniff可以通过man in the middle攻击来截获https的消息。
图片来源于红黑网络

证书被伪造后,客户端的浏览器弹出提示。

如果我们此时点击继续,则https 通话就被成功窃听。

代理

代理事实上也是一个主机 M,但是这个主机 M 不能读取和修改任何会话,否则的话,一样会出现证书被伪造的提示。

TLS 加密的定义

TLS如何定义加密过程的

证书验证

密钥的生成过程