SSL与TLS协议详解

写在最前面的话:这篇文章是我借鉴了Eric Rescorla的《SSL and TLS》一书之后对该书的前半部分内容整合而做。如您需要开发围绕SSL、TLS的程序建议参阅原著或者RFC相关文档。

一、关于SSL、TLS与HTTPS的三两事

什么是SSL、TLS:

众所周知,真正的通信实际上是两台主机之间的进程在交换数据,而运输层作为整个网络最关键的从层次之一,扮演沿着向上层(应用层)提供通信服务的角色。想要剖析运输层的数据安全传输策略就一定无法绕开三个至关重要的协议,它们分别是HTTPS协议、SSL协议、TSL协议。SSL(Secure Sockets Layer)协议既安全套接字层协议,TLS(Transport Layer Security)协议即安全传输层协议

诞生背景:

随着网上银行和电子商务的兴起,人们需要一种技术来保障Word Wide Web(WWW)通讯的安全,而当时现有的http协议一直是明文传输。在这一背景下Netscape(网景)公司于1990年开发出了SSL(Secure Sockets Layer)安全套接字层(此时的Netscape Navigator浏览器仍统治互联网浏览器市场)。该协议的主要任务是提供数据加密、身份验证和消息完整性验证服务。此时的SSl版本号为SSL 1.0,由于多方面原因第一个版本从未发布过。第二版既SSL 2.0则于1994年发布,但是由于Netscape的开发人员闭门造车基本没有与其他业内安全专家商讨,所以存在弱点,被认为是失败的协议,最终退出了历史舞台。时间来到了1995年我们的主角SSL 3.0终于发布,虽然与早先的版本协议名称相似,但是SSl 3.0被完全重新设计,该协议的主要任务不变且设计沿用至今。HTTP作为第一个使用SSL保证安全的应用层协议,HTTP over SSL(HTTPS)应运而生,后来HTTPS在RFC2818被标准化,这一设计也就沿用至今。但SSL的进化没有停止,现如今的HTTPS实际上是HTTP over SSL/TSL,TSL实际上可以算作SSL的升级版本但是由于IETF标准化被更名为TSL(Transport Layer Security,传输层安全)。最早的TLS 1.0版本与1999年发布且与SSL 3.0没有太大区别。TLS 1.1与2006年发布,时隔多年但也只是修复了一些关键的安全问题。TLS 1.2于2008年发布,该版本添加了对已验证加密的支持,并且使协议完全弹性化,该版本被沿用至今。最新的TLS 1.3版本针对安全强化及效率提升方面进行了大量修改,相继推出了20多个草案版本并且即将完成最终的标准化,将会得到广泛的支持。

HTTPS、SSL与TLS的关系:

SSL严格意义上将SSL是介于网络层协议和应用层协议之间的一种协议层。通过与HTTP协议搭配产生了HTTPS协议,您可以理解为HTTP+SSL=HTTPS(阅读下文您将理解为什么网络专家要这么设计)。现如今SSL经过三代更新,在SSLv3.0之后正式更名为TLS1.0。也可以理解为TLS1.0实际上是SSLv3.1。

二、SSL协议详解

SSL介绍:

SSL(Secure Socket Layer)协议是一种在主机之间提供安全数据传输的协议,它具有数据加密以及身份验证的功能。传输数据在安全通道上是透明的,这说明它并不对数据进行修改或变更,数据在传输之前就完成了加密,一端发送的数据完全是另一端读取的内容。得益于透明传输,几乎所有基于TCP的协议稍加改动就可以在SSL上运行,非常便捷。

最常见SSL的工作流程:

1、整体概述

SSL的连接分为两个阶段(握手阶段和数据传输阶段),握手阶段用于对服务器进行认证并确定用于保护数据传输的加密 **。传输任何数据之前都必须完成握手操作,因为握手阶段完成后数据就会被分成一系列经过保护的记录进行传输。

2、握手阶段

SSL协议总共有四种握手形式:
1、Full Handshake:客户端和服务器端双方从无到有建立SSL连接,也被成为全流程握手,本文将重点介绍。
2、Resum session Handshake:客户端和服务器端曾经建立过连接,但被中断了,SSL的会话信息被保留了下来,只需 要执行部分握手流程就可建立SSL连接
3、Server Re-negotiation Handshake:客户端和服务器端已经建立了连接,但服务器端要求重新对**进行协商,这时只需要执行部分握手流程就可以重建连接。
4、Client Re-negotiation Handshake:客户端和服务器端已经建立连接,但客户端端要求重新协商**,同上只需执行部分握手流程。
本文将介绍全流程握手(并且只介绍SSL的最基本模式—使用RSA只进行服务器认证的模式),全流程握手的目的有三。
第一,客户端和服务器需要在保护数据的加密算法上达成一致。
第二,客户端和服务器需要确定加密算法的**。
第三(此项 可选择),服务端对客户端进行认证
整个握手流程大致如下*
SSL与TLS协议详解
(请注意,并非一个阶段对应一个握手消息,有可能一个阶段对应多个握手消息,本流程只是为了让读者对SSL有个初步了解):*
(1) 客户端将自己所支持的加密算法写入一个列表,并着手生成一个**,在该**产生过程中会有一个随机生成的并用作输入的随机数(请联系RSA**生成时所使用随机数)。客户端将该算法列表和该输入数发送给服务器端
实际
(2) 服务器在收到客户端发送的数据之后根据列表的内容选择一个自己也支持的加密算法,然后服务器会将自己用于认证服务器的标识以及一个同作为**产生部分输入的随机数制作成证书并将其连同自己选中的加密算法发回客户端。
(3) 客户端在收到服务器返回的数据之后先对服务器的证书进行验证并获取服务器的公钥(非对称加密中的公钥)。然后再生成一个名为pre_master_secret的随机密码串并使用服务器的公钥进行加密,之后将其发送给服务端。
(4) 服务器在收到master_secert之后用自己的私钥进行解密,在获得了双方的随机数之后服务端和客户端都会计算出加密和MAC**。这一步在安全传输中的作用举足轻重,但是在握手流程中不进行详细的解释,会在下文进行详细的补充。
(5) 客户端将本次所有握手消息的MAC值发送给服务端
(6) 服务器同将本次所有握手消息的MAC值发送给客户端
经过该握手阶段客户端和服务端确定了要使用的加密算法(第一步、第二部)并确定了加***(第三步、第四步)。第五步和第六步用来防止握手本身遭到中间人攻击(篡改)。

实际的全流程握手消息
(1) 第一步只有一条单一的握手消息ClientHello。
(2) 第二步对应四条握手消息,也就是说服务器端向客户端回复了三条消息。他们分别是:
第一条:Server Hello消息,包含服务器选择的算法以及上文提到的随机数。
第二条:Service Certificate消息,包含服务器的公钥(一般情况下是RSA)的证书。
第三条:Client Certificate Requst消息,服务器端索要客户端证书/公钥。
第四条:Server Hello Done消息,表示握手阶段完成。需要这个消息的原因是SSL的诸多变种版本会在第二步发送不只三条握手消息,所以需要一个消息告诉客户端本次握手消息发送完毕。
(3) 第三步包含一条消息,ClientKeyExchange消息,其中包含了一个随机产生的服务器RSA**加密的**。

(4) 第四步客户端与服务器端并不发送消息,双方根据pre_master_secret以及双方的随机数各自计算出加密和MAC**。
(5) 第五步包含客户端向服务器端发送的两条握手消息。它们分别是:

第一条:ChangeCipherSpec 消息,其表示了记录加密及认证的改变。当双方确定了一组新的**,就发送该消息,表示开启新的**。
第二条:Finished消息,这个消息表示本次握手传输完成。Finished消息用于校验各个握手阶段。

(6) 第六步:
第一条:ChangeCipherSpec消息,服务器端也需要发送确认开启新的**的消息。
第二条:Finished消息,校验握手阶段结束。

3、数据传输阶段

建立了连接之后SSl的数据传输是通过SSL记录协议进行数据传输的。与TCP协议大同小异,SSL记录协议将数据流进行分割,得到一系列的片段之后加以传输。值得一提的是SSL对每一个片段都采用了独立的保护机制,在接收方需要对收到的每一条数据都进行解密和验证。
对数据的完整性保护是通过在数据片段中插入MAC实现的,MAC附加到数据片段的尾部,在接收方实现验证。
对数据的加密是整段进行的,整一个数据片段(连同MAC)都要进行加密处理,在接收端进行解密。
对于pre_master_secert的(握手流程第四步)补充说明:在pre_master_secert交换完毕之后,服务器端和客户端都需要将其扩展成独特的加***来实现加密和认证等任务。这种扩展需要使用一种**导出函数来实现(值得一提的是SSLv3和TLS的导出函数相似但是具体变换各有不同)。具体过程就是客户端/服务器端双方在收到pre_master_secert后将其和自己的随机数合并生成master_secert,通过master_secert和随机数的配合又生成了各自的**分组,并将**分组应用到了之后的通讯过程中。
SSL与TLS协议详解

4、警示协议和关闭协议

设计警示协议的目的是一方可以向另一方报告例外情况,警示协议包含突发情况的严重程度和相应的描述。警示分为警告(warning)和致命(fatal)两种等级。fatal警示会终止连接,warning会继续执行。警示的种类非常多,本文只介绍连接关闭警示。
当客户端想要关闭连接的时候会使用close_notify警告来表示即将关闭连接,随后再发送一条包含TCP FIN的消息。服务器端会在接收到这两条消息后回复自己的TCP FIN消息,这样就表示它关闭了连接并不再发送任何数据。(对于到底是谁发送close_notify报警,SSL规范并没有叙述详细,但是理论上通讯双方都可以发送)

三、TLS详解

1、TLS的工作流程

上文已经多次提到TLS的设计原理与SSLv3相同(握手流程及数据传输流程相同)二者最明显的区别就是它们所支持的加密算法不同,这也造成了TLS和SSLv3不可相互操作。
TLS和SSL的具体差异如下:
MAC算法不同:TLS使用基于异或运算的HMAC算法,在不改变安全程度的情况下优化了效率。
报警报文不同:在基于SSL支持的报警报文上TLS补充了很多报警报文(如未知CA、记录溢出、拒绝访问、解密失败等)。
密文组和客户端证书不同:TLS不支持Fortezza**交换、加密算法和客户证书。
握手消息部分不同:certificate_verify和finished消息计算输入时存在少许差别。
Master_secret的计算方式不同
对数据的填充规格不同:对于长度达不到数据字段要求的数据,SSLv3要求填充后其长度要达到密文块长度的最小整数倍。而TLS可以是任意整数倍(有效对抗攻击者对报文长度的分析)。