SSL/TLS
是什么
计算机网络的OSI七层模型和TCP/IP四层模型想必大家都知道。
其中SSL/TLS是一种介与于传输层(比如TCP/IP)和应用层(比如HTTP)的协议。
它通过”握手协议(Handshake Protocol)”和”传输协议(Record Protocol)”来解决传输安全的问题。
SSL/TLS是一个可选层,没有它,使用HTTP也可以通信,它存在的目的就是为了解决安全问题,这也就是HTTPS相对于HTTP的精髓所在。
- SSL:(Secure Socket Layer,安全套接字层)
为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取。当前版本为3.0。它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输。 SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
- TLS:(Transport Layer Security,传输层安全协议)
用于两个应用程序之间提供保密性和数据完整性。
TLS 1.0是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本,可以理解为SSL 3.1,它是写入了 RFC 的。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。
SSL/TLS协议提供的服务主要有:
认证用户和服务器,确保数据发送到正确的客户机和服务器; 加密数据以防止数据中途被窃取; 维护数据的完整性,确保数据在传输过程中不被改变。
发展历史
SSL/TLS 协议发展历史参看下表。
Protocol | Year | RFC | Description |
---|---|---|---|
SSL 1.0 | 1994 | NetScape公司设计1.0版 但是未发布 | |
SSL 2.0 | 1995.02 | NetScape公司发布SSL 2.0版 | |
SSL 3.0 | 1996 | RFC 6101 | NetScape公司发布SSL 3.0版 |
TLS 1.0 | 1999 | RFC 2246 | IETF将SSL标准化 改名为TLS 发布1.0版 |
TLS 1.1 | 2006.04 | RFC 4346 | 发布TLS1.1版 |
TLS 1.2 | 2008.08 | RFC 5246 | 发布TLS1.2版 |
TLS 1.3 | TLS 1.3还是一个互联网草案 待发布 |
SSL/TLS运行过程
过程概述
上面提到SSL/TLS有两个阶段握手协议和传输协议,握手协议就是建立起连接的过程,这个阶段采用非对称加密,这个过程完毕后会生成一个对话秘钥,从而传输协议过程,就是用这个对话秘钥使用对称加密进行传输。
之所以这样做,是因为,非对称加密是很耗性能的。
而握手协议过程中,使用数字证书保证了公钥的安全性。
当然这个过程既可以双向证书验证,也可以只验证服务端的证书单向证书验证。
流程图
客户端发出请求(ClientHello)
由于客户端(如浏览器)对一些加解密算法的支持程度不一样,但是在TLS协议传输过程中必须使用同一套加解密算法才能保证数据能够正常的加解密。
在TLS握手阶段,客户端首先要告知服务端,自己支持哪些加密算法,所以客户端需要将本地支持的加密套件(Cipher Suite)的列表传送给服务端。
除此之外,客户端还要产生一个随机数,这个随机数一方面需要在客户端保存,另一方面需要传送给服务端,客户端的随机数需要跟服务端产生的随机数结合起来产生后面要讲到的 Master Secret。
综上,在这一步,客户端主要向服务器提供以下信息:
-
支持的协议版本,比如TLS 1.0版
-
一个客户端生成的随机数,稍后用于生成”对话密钥”
-
支持的加密方法,比如RSA公钥加密
-
支持的压缩方法
服务器回应(SeverHello)
上图中,从Server Hello到Server Done,有些服务端的实现是每条单独发送,有服务端实现是合并到一起发送。Sever Hello和Server Done都是只有头没有内容的数据。
服务端在接收到客户端的Client Hello之后,服务端需要将自己的证书发送给客户端。这个证书是对于服务端的一种认证。例如,客户端收到了一个来自于称自己是www.alipay.com的数据,但是如何证明对方是合法的alipay支付宝呢?这就是证书的作用,支付宝的证书可以证明它是alipay,而不是财付通。证书是需要申请,并由专门的数字证书认证机构(CA)通过非常严格的审核之后颁发的电子证书。颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被串改。另外,证书还有个有效期。
在服务端向客户端发送的证书中没有提供足够的信息(证书公钥)的时候,还可以向客户端发送一个 Server Key Exchange,
此外,对于非常重要的保密数据,服务端还需要对客户端进行验证,以保证数据传送给了安全的合法的客户端。服务端可以向客户端发出 Cerficate Request 消息,要求客户端发送证书对客户端的合法性进行验证。比如,金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供USB密钥,里面就包含了一张客户端证书。
跟客户端一样,服务端也需要产生一个随机数发送给客户端。客户端和服务端都需要使用这两个随机数来产生Master Secret。
最后服务端会发送一个Server Hello Done消息给客户端,表示Server Hello消息结束了。
综上,在这一步,服务器的回应包含以下内容:
-
确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信
-
一个服务器生成的随机数,稍后用于生成”对话密钥”
-
确认使用的加密方法,比如RSA公钥加密
-
服务器证书
客户端回应(Certificate Verify)
Client Key Exchange
如果服务端需要对客户端进行验证,在客户端收到服务端的 Server Hello 消息之后,首先需要向服务端发送客户端的证书,让服务端来验证客户端的合法性。
Certificate Verify
接着,客户端需要对服务端的证书进行检查,如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。如果证书没有问题,客户端就会从服务器证书中取出服务器的公钥。然后,向服务器发送下面三项信息:
一个随机数。该随机数用服务器公钥加密,防止被窃听 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验 上面第一项的随机数,是整个握手阶段出现的第三个随机数,它是客户端使用一些加密算法(例如:RSA, Diffie-Hellman)产生一个48个字节的Key,这个Key叫 PreMaster Secret,很多材料上也被称作 PreMaster Key。
ChangeCipherSpec
ChangeCipherSpec 是一个独立的协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到之前协商好的加密套件(Cipher Suite)的状态,准备使用之前协商好的加密套件加密数据并传输了。
在ChangecipherSpec传输完毕之后,客户端会使用之前协商好的加密套件和Session Secret加密一段 Finish 的数据传送给服务端,此数据是为了在正式传输应用数据之前对刚刚握手建立起来的加解密通道进行验证。
服务器的最后回应(Server Finish)
服务端在接收到客户端传过来的 PreMaster 加密数据之后,使用私钥对这段加密数据进行解密,并对数据进行验证,也会使用跟客户端同样的方式生成 Session Secret,一切准备好之后,会给客户端发送一个 ChangeCipherSpec,告知客户端已经切换到协商过的加密套件状态,准备使用加密套件和 Session Secret加密数据了。
之后,服务端也会使用 Session Secret 加密一段 Finish 消息发送给客户端,以验证之前通过握手建立起来的加解密通道是否成功。
根据之前的握手信息,如果客户端和服务端都能对Finish信息进行正常加解密且消息正确的被验证,则说明握手通道已经建立成功,接下来,双方可以使用上面产生的Session Secret对数据进行加密传输了。
几个 Secret
Secret Keys
上面的分析和讲解主要是为了突出握手的过程,所以PreMaster secret,Master secret,session secret都是一笔带过。
但是对于Https,SSL/TLS深入的理解和掌握,这些Secret Keys是非常重要的部分。所以,准备把这些Secret Keys抽出来单独分析和讲解。
我们先来看看这些Secret Keys的生成过程以及作用流程图:
PreMaster secret
PreMaster Secret是在客户端使用RSA或者Diffie-Hellman等加密算法生成的。
它将用来跟服务端和客户端在Hello阶段产生的随机数结合在一起生成 Master Secret。在客户端使用服务端的公钥对PreMaster Secret进行加密之后传送给服务端,服务端将使用私钥进行解密得到PreMaster secret。也就是说服务端和客户端都有一份相同的PreMaster secret和随机数。
PreMaster secret前两个字节是TLS的版本号,这是一个比较重要的用来核对握手数据的版本号,因为在Client Hello阶段,客户端会发送一份加密套件列表和当前支持的SSL/TLS的版本号给服务端,而且是使用明文传送的,如果握手的数据包被破解之后,攻击者很有可能串改数据包,选择一个安全性较低的加密套件和版本给服务端,从而对数据进行破解。所以,服务端需要对密文中解密出来对的PreMaster版本号跟之前Client Hello阶段的版本号进行对比,如果版本号变低,则说明被串改,则立即停止发送任何消息。
关于PreMaster Secret(Key)的计算请参考 Https SSL/TLS PreMaster/Master Secret(Key)计算。
Master secret
上面已经提到,由于服务端和客户端都有一份相同的PreMaster secret和随机数,这个随机数将作为后面产生Master secret的种子,结合PreMaster secret,客户端和服务端将计算出同样的Master secret。
Master secret是有系列的hash值组成的,它将作为数据加解密相关的secret的 Key Material 的一部分。
Key Material最终解析出来的数据如下:
其中,write MAC key,就是session secret或者说是session key。Client write MAC key是客户端发数据的session secret,Server write MAC secret是服务端发送数据的session key。MAC(Message Authentication Code),是一个数字签名,用来验证数据的完整性,可以检测到数据是否被串改。
应用
安全性
SecurityPortal在2000年底有一份文章《The End of SSL and SSH?》激起了很多的讨论。
目前也有一些成熟的工具如 dsniff 可以通过 man in the middle 攻击来截获 https 的消息。
从上面的原理可知,SSL的结构是严谨的,问题一般出现在实际不严谨的应用中。
常见的攻击就是middle in the middle攻击,它是指在A和B通信的同时,有第三方C处于信道的中间,可以完全听到A与B通信的消息,并可拦截,替换和添加这些消息。
-
SSL可以允许多种密钥交换算法,而有些算法,如DH,没有证书的概念,这样A便无法验证B的公钥和身份的真实性,从而C可以轻易的冒充,用自己的密钥与双方通信,从而窃听到别人谈话的内容。
-
而为了防止middle in the middle攻击,应该采用有证书的密钥交换算法。
-
有了证书以后,如果C用自己的证书替换掉原有的证书之后,A的浏览器会弹出一个警告框进行警告,但又有多少人会注意这个警告呢?
由于美国密码出口的限制,IE,netscape等浏览器所支持的加密强度是很弱的,如果只采用浏览器自带的加密功能的话,理论上存在被破解可能。
总结
SSL客户端(也是TCP的客户端)在TCP链接建立之后,发出一个ClientHello来发起握手,这个消息里面包含了自己可实现的算法列表和其它一些需要的消息,SSL的服务器端会回应一个ServerHello,这里面确定了这次通信所需要的算法,然后发过去自己的证书(里面包含了身份和自己的公钥)。
Client在收到这个消息后会生成一个秘密消息,用SSL服务器的公钥加密后传过去,SSL服务器端用自己的私钥解密后,会话密钥协商成功,双方可以用同一份会话密钥来通信了。