tcp/ip|网络协议--SSL/TLS

一、简介 SSL(Secure Socket Layer 安全套接层)最初是由网景公司(Netscape)研发,在SSL更新到3.0时,被IETF(互联网工程任务组)标准化后写入RFC, IETF对SSL3.0进行了标准化为TLS1.0,并添加了少数机制,两者差别极小,TLS可以理解为SSL3.1。
二、SSL和TLS的区别 2.1SSL SSL(Secure Socket Layer,安全套接字层),位于TCP/IP协议和应用层协议之间的一种协议层。SSL通过互相认证、使用数字签名确保完整性、使用加密确保私密性,以实现客户端和服务器之间的安全通讯。该协议由两层组成:SSL记录协议和SSL握手协议。SSL由从前的网景公司开发,有1,2,3三个版本,但现在只使用版本3。

  • SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。
  • SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
SSL协议提供的服务主要有:
1) 认证用户和服务器,确保数据发送到正确的客户机和服务器;、
2) 加密数据以防止数据中途被窃取;
【tcp/ip|网络协议--SSL/TLS】3) 维护数据的完整性,确保数据在传输过程中不被改变
2.2 TLS TLS:(Transport Layer Security,传输层安全协议),用于两个应用程序之间提供保密性和数据完整性。该协议由两层组成:TLS记录协议和TLS握手协议。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。TLS有1.0,1.1,1.2三个版本,默认使用1.0。
TLS 记录协议提供的连接安全性具有两个基本特性:
  • 私有: 对称加密用以数据加密(DES 、RC4 等)。对称加密所产生的密钥对每个连接都是唯一的,且此密钥基于另一个协议(如握手协议)协商。记录协议也可以不加密使用。
  • 可靠: 信息传输包括使用密钥的MAC进行信息完整性检查。安全哈希功能( SHA、MD5 等)用于 MAC 计算。记录协议在没有 MAC 的情况下也能操作,但一般只能用于这种模式,即有另一个协议正在使用记录协议传输协商安全参数。
TLS的最大优势就在于:TLS是独立于应用协议。高层协议可以透明地分布在TLS协议上面。然而, TLS 标准并没有规定应用程序如何在TLS上增加安全性;它把如何启动 TLS 握手协议以及如何解释交换的认证证书的决定权留给协议的设计者和实施者来判断。
2.3 区别
在TLS与SSL3.0之间存在着显著的差别,主要是它们所支持的加密算法不同,所以TLS与SSL3.0不能互操作。
1)版本号:TLS记录格式与SSL记录格式相同,但版本号的值不同,TLS的版本1.0使用的版本号为SSLv3.1。
2)报文鉴别码:SSLv3.0和TLS的MAC算法及MAC计算的范围不同。TLS使用了RFC-2104定义的HMAC算法。SSLv3.0使用了相似的算法,两者差别在于SSLv3.0中,填充字节与密钥之间采用的是连接运算,而HMAC算法采用的是异或运算。但是两者的安全程度是相同的。
3)伪随机函数:TLS使用了称为PRF的伪随机函数来将密钥扩展成数据块,是更安全的方式。
4)报警代码:TLS支持几乎所有的SSLv3.0报警代码,而且TLS还补充定义了很多报警代码,如解密失败(decryption_failed)、记录溢出(record_overflow)、未知CA(unknown_ca)、拒绝访问(access_denied)等。
5)密文族和客户证书:SSLv3.0和TLS存在少量差别,即TLS不支持Fortezza密钥交换、加密算法和客户证书。
6)certificate_verify和finished消息:SSLv3.0和TLS在用certificate_verify和finished消息计算MD5和SHA-1散列码时,计算的输入有少许差别,但安全性相当。
7)加密计算:TLS与SSLv3.0在计算主密值(master secret)时采用的方式不同。
8)填充:用户数据加密之前需要增加的填充字节。在SSL中,填充后的数据长度要达到密文块长度的最小整数倍。而在TLS中,填充后的数据长度可以是密文块长度的任意整数倍(但填充的最大长度为255字节),这种方式可以防止基于对报文长度进行分析的攻击。
三、协议原理 3.1 两个阶段 TLS 协议可分为两个阶段:
1、握手(Handshake)阶段,其目的是通信双方约定在数据传输阶段使用的加解密算法及密钥(为效率考虑,在数据传输阶段会使用对称密钥算法);
2、数据传输阶段,即发送到网络前加密数据,从网络收到数据后解密数据。
3.2 TLS协议握手过程 tcp/ip|网络协议--SSL/TLS
文章图片

下面来介绍一下 Handshake 的具体过程。
第 1 步、客户端发送 ClientHello 报文。其主要作用是告诉服务器,本客户端所支持的 TLS 协议版本,以及所支持的加密算法等等。
第 2 步、服务器发送 ServerHello 报文。其主要作用是服务器选择一个它认为安全的,且双方都支持的加密算法;如果服务器认为客户端所有支持的加密算法都不安全,则服务器可以发送一个 ALERT 报文(ALERT 报文是 TLS 顶级报文,参见 1.2 )。
第 3 步、服务器发送 Certificate 报文。其主要作用是服务器发送自己的证书给客户端。
第 4 步、服务器发送 ServerKeyExchange 。其主要作用是提供一些信息,以便双方有足够的信息来约定一个数据传输阶段所使用的对称密钥算法的密钥。这个报文是可选的,如果使用 Diffie-Hellman 方式来约定密钥,则这个是必须的;如果是 RSA 方式来约定密钥,它可以省略,参见后面介绍的 ClientKeyExchange 报文。
第 5 步、服务器发送 CertificateRequest 。其作用是开启“双向认证(Mutual authentication)”模式,即不仅客户端要验证服务器,而且服务器还要验证客户端。这种方式在 https 网站中很少使用,如果对 https 网站进行抓包分析,一般都不会有这个报文。
第 6 步,服务器发送 ServerHelloDone 。其作用是告诉客户端
第 7 步、客户端发送 Certificate 报文(仅当客户端收到了 CertificateRequest 时才发送,即服务器开启了双向认证)。其主要作用是客户端发送自己的证书给服务器。
第 8 步、客户端发送 ClientKeyExchange 报文。其主要作用是提供一些信息,以便双方有足够的信息来约定一个数据传输阶段所使用的对称密钥算法的密钥。如果是 RSA 方式,则客户端生成一个对称密钥算法的密钥后,使用服务器的公钥进行加密后传送给服务器。如果是 Diffie-Hellman 方式,则传送必要信息以便双方可以按约定方式生成同一个密钥。
第 9 步、客户端发送 CertificateVerify 报文(仅当客户端收到了 CertificateRequest 时才发送,即服务器开启了双向认证)。主要作用是客户端发送一段它签名的信息给服务器,这样服务器使用客户端的公钥就可以验证签名,从而验证客户端。
第 10 步、客户端发送 ChangeCipherSpec 报文,告诉服务器你可以使用加密模式了。注: ChangeCipherSpec 报文不属于 Handshake 报文,它是 TLS 顶级报文。
第 11 步、客户端发送 Finished 报文,告诉服务器我准备好加密通信了。
第 12 步、服务器发送 ChangeCipherSpec 报文,告诉客户端你可以使用加密模式了。
第 13 步、服务器发送 Finished 报文,告诉客户端我准备好加密通信了。至此,握手结束。
3.3 协议格式 tcp/ip|网络协议--SSL/TLS
文章图片

3.3.1 TLS报文头
TLS 报文头占 5 字节,第 1 字节是类型(目前有 4 种类型),第 2-3 字节是版本(目前有 4 种版本),第 4-5 字节是长度(不包含报文头本身长度),其格式为:
tcp/ip|网络协议--SSL/TLS
文章图片

3.3.2 HandShake报文
HandShake报文格式 如下:
tcp/ip|网络协议--SSL/TLS
文章图片

注 1:共有 10 种类型的 Handshake 报文,每种类型的具体格式可参考:Traffic Analysis of an SSL/TLS Session
注 2:多个 Handshake 报文可以组合为一个 TLS Record,上面演示中就有两个 Handshake 报文。
3.3.2.1 Client Hello报文
报文格式
tcp/ip|网络协议--SSL/TLS
文章图片

tcp/ip|网络协议--SSL/TLS
文章图片

client hello 握手第一步是客户端向服务端发送 Client Hello 消息,这个消息里包含了一个客户端生成的随机数 Random1、客户端支持的加密套件(Support Ciphers)和 SSL Version 等信息。抓包示例如下:
tcp/ip|网络协议--SSL/TLS
文章图片


ClientHello中涉及到的消息具体如下:
  • 客户端版本
    按优先级列出客户端支持的协议版本,首选客户端希望支持的最新协议版本。
  • 客户端随机数Random
  • 会话ID(Session id)
    如果客户端第一次连接到服务器,那么这个字段就会保持为空。上图中该字段为空,说明这是第一次连接到服务器。
    如果该字段不为空,说明以前是与服务器有连接的,在此期间,服务器将使用Session ID映射对称密钥,并将Session ID存储在客户端浏览器中,为映射设置一个时间限。如果浏览器将来连接到同一台服务器(在时间到期之前),它将发送Session ID,服务器将对映射的Session ID进行验证,并使用以前用过的对称密钥来恢复Session,这种情况下不需要完全握手。也叫作SSL会话恢复。后面会有介绍。
  • 加密套件:
    客户端会给服务器发送自己已经知道的密码套件列表,这是由客户按优先级排列的,但完全由服务器来决定发送与否。TLS中使用的密码套件有一种标准格式。上面的报文中,客户端发送了74套加密套件。服务端会从中选出一种来作为双方共同的加密套件。
  • 压缩方法:
    为了减少带宽,可以进行压缩。但从成功攻击TLS的事例中来看,其中使用压缩时的攻击可以捕获到用HTTP头发送的参数,这个攻击可以劫持Cookie,这个漏洞我们称为CRIME。从TLS 1.3开始,协议就禁用了TLS压缩。
  • 扩展包:
    其他参数(如服务器名称,填充,支持的签名算法等)可以作为扩展名使用。
    这些是客户端问候的一部分,如果已收到客户端问候,接下来就是服务器的确认,服务器将发送服务器问候。
3.3.2.2 Server Hello协议
收到客户端问候之后服务器必须发送服务器问候信息,服务器会检查指定诸如TLS版本和算法的客户端问候的条件,如果服务器接受并支持所有条件,它将发送其证书以及其他详细信息,否则,服务器将发送握手失败消息。
如果接受,第二步是服务端向客户端发送 Server Hello 消息,这个消息会从 Client Hello 传过来的 Support Ciphers 里确定一份加密套件,这个套件决定了后续加密和生成摘要时具体使用哪些算法,另外还会生成一份随机数 Random2。注意,至此客户端和服务端都拥有了两个随机数(Random1+ Random2),这两个随机数会在后续生成对称秘钥时用到。
tcp/ip|网络协议--SSL/TLS
文章图片

ServerHello中涉及到的具体参数:
  • 服务器版本Version:
    服务器会选择客户端支持的最新版本。
  • 服务器随机数Random:
    服务器和客户端都会生成32字节的随机数。用来创建加密密钥。
  • 加密套件:
    服务器会从客户端发送的加密套件列表中选出一个加密套件。
  • 会话ID(Session ID):
    ?服务器将约定的Session参数存储在TLS缓存中,并生成与其对应的Session id。它与Server Hello一起发送到客户端。客户端可以写入约定的参数到此Session id,并给定到期时间。客户端将在Client Hello中包含此id。如果客户端在此到期时间之前再次连接到服务器,则服务器可以检查与Session id对应的缓存参数,并重用它们而无需完全握手。这非常有用,因为服务器和客户端都可以节省大量的计算成本。
    ??在涉及亚马逊和谷歌等流量巨大的应用程序时,这种方法存在缺点。每天都有数百万人连接到服务器,服务器必须使用Session密钥保留所有Session参数的TLS缓存。这是一个巨大的开销。
    为了解决这个问题,在扩展包里加入了Session Tickets, 在这里,客户端可以在client hello中指定它是否支持Session Ticket。然后,服务器将创建一个新的会话票证(Session Ticket),并使用只有服务器知道的经过私钥加密的Session参数。它将存储在客户端上,因此所有Session数据仅存储在客户端计算机上,但Ticket仍然是安全的,因为该密钥只有服务器知道。
    ??此数据可以作为名为Session Ticket的扩展包含在Client Hello中。
  • 压缩算法:
    如果支持,服务器将同意客户端的首选压缩方法。
  • 扩展包
这个阶段之后,客户端服务端知道了下列内容:
  1. SSL版本
  2. 密钥交换、信息验证和加密算法
  3. 压缩方法
  4. 有关密钥生成的两个随机数。
3.3.2.3 Server Key Exchange (可选)
根据之前在ClientHello消息中包含的CipherSuite信息,决定了密钥交换方式(例如RSA或者DH),因此在Server Key Exchange消息中便会包含完成密钥交换所需的一系列参数。
tcp/ip|网络协议--SSL/TLS
文章图片


因为这里是DH算法,所以需要发送服务器使用的DH参数。RSA算法不需要这一步。
在Diffie-Hellman中,客户端无法自行计算预主密钥; 双方都有助于计算它,因此客户端需要从服务器获取Diffie-Hellman公钥。
由上图可知,此时密钥交换也由签名保护。

3.3.2.4 Certificata Request (可选) -- 可以是单向身份认证,也可以是双向身份认证
这一步是可选的,如果在对安全性要求高的常见可能用到。服务器用来验证客户端。服务器端发出Certificate Request消息,要求客户端发他自己的证书过来进行验证。该消息中包含服务器端支持的证书类型(RSA、DSA、ECDSA等)和服务器端所信任的所有证书发行机构的CA列表,客户端会用这些信息来筛选证书。
如果服务器发送了 CertificateRequest就意味着开启“双向认证”。和“单向认证”相比,“双向认证”在握手阶段多了下面 3 种报文:
  • 服务器发送的 CertificateRequest
  • 客户端发送的 CertificateCertificateVerify
3.3.2.5 Server Hello Done
该消息表示服务器已经将所有信息发送完毕,接下来等待客户端的消息。
tcp/ip|网络协议--SSL/TLS
文章图片

3.3.2.6 Certificate(可选,双向认证)
如果在第二阶段服务器端要求发送客户端证书,客户端便会在该阶段将自己的证书发送过去。服务器端在之前发送的Certificate Request消息中包含了服务器端所支持的证书类型和CA列表,因此客户端会在自己的证书中选择满足这两个条件的第一个证书发送过去。若客户端没有证书,则发送一个no_certificate警告。
3.3.2.7 Client Key exchange
根据之前从服务器端收到的随机数,按照不同的密钥交换算法,算出一个pre-master,发送给服务器,服务器端收到pre-master算出main master。而客户端当然也能自己通过pre-master算出main master。如此以来双方就算出了对称密钥。
如果是RSA算法,会生成一个48字节的随机数,然后用server的公钥加密后再放入报文中。如果是DH算法,这是发送的就是客户端的DH参数,之后服务器和客户端根据DH算法,各自计算出相同的pre-master secret.
tcp/ip|网络协议--SSL/TLS
文章图片


3.3.2.8 Certificata verify(可选,双向认证)
只有在客户端发送了自己证书到服务器端,这个消息才需要发送。其中包含一个签名,对从第一条消息以来的所有握手消息的HMAC值(用master_secret)进行签名。
完成握手协议,建立SSL连接。

3.3.2.9 ChangeCipherSpec
编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送(ChangeCipherSpec是一个独立的协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到之前协商好的加密套件(Cipher Suite)的状态,准备使用之前协商好的加密套件加密数据并传输了)。
tcp/ip|网络协议--SSL/TLS
文章图片


3.3.2.10 Client Finished
客户端握手结束通知, 表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验(使用HMAC算法计算收到和发送的所有握手消息的摘要,然后通过RFC5246中定义的一个伪函数PRF计算出结果,加密后发送。此数据是为了在正式传输应用数据之前对刚刚握手建立起来的加解密通道进行验证。)
3.3.2.10 Server Finished
服务端握手结束通知。
  1. 使用私钥解密加密的Pre-master数据,基于之前(Client Hello 和 Server Hello)交换的两个明文随机数 random_C 和 random_S,计算得到协商密钥:enc_key=Fuc(random_C, random_S, Pre-Master);
  2. 计算之前所有接收信息的 hash 值,然后解密客户端发送的 encrypted_handshake_message,验证数据和密钥正确性;
  3. 发送一个 ChangeCipherSpec(告知客户端已经切换到协商过的加密套件状态,准备使用加密套件和 Session Secret加密数据了)
  4. 服务端也会使用 Session Secret 加密一段 Finish 消息发送给客户端,以验证之前通过握手建立起来的加解密通道是否成功。
根据之前的握手信息,如果客户端和服务端都能对Finish信息进行正常加解密且消息正确的被验证,则说明握手通道已经建立成功,接下来,双方可以使用上面产生的Session Secret对数据进行加密传输了。

3.3.3 SSL记录协议
SSL记录协议为SSL连接提供两种服务:机密性和报文完整性。
在SSL协议中,所有的传输数据都被封装在记录中。记录是由记录头和记录数据(长度不为0)组成的。所有的SSL通信都使用SSL记录层,记录协议封装上层的握手协议、报警协议、修改密文协议。SSL记录协议包括记录头和记录数据格式的规定。
SSL记录协议定义了要传输数据的格式,它位于一些可靠的传输协议之上(如TCP),用于各种更高层协议的封装。主要完成分组和组合、压缩和解压缩,以及消息认证和加密等。
SSL记录协议主要操作流程如图所示:
tcp/ip|网络协议--SSL/TLS
文章图片


图中的五个操作简单介绍如下:
1)每个上层应用数据被分成214字节或更小的数据块。记录中包含类型、版本号、长度和数据字
段。
2)压缩是可选的,并且是无损压缩,压缩后内容长度的增加不能超过1024字节。
3)在压缩数据上计算消息认证MAC。
4)对压缩数据及MAC进行加密。
5)增加SSL记录。
SSL记录协议字段的结构如图8所示。
tcp/ip|网络协议--SSL/TLS
文章图片

1)内容类型(8位):封装的高层协议。
2)主要版本(8位):使用的SSL主要版本。对于SSL v3已经定义的内容类型是握手协议、警告协议、改变密码格式协议和应用数据协议。
3)次要版本(8位):使用的SSL次要版本。对于SSL v3.0,值为0。
4)压缩长度(16位):明文数据(如果选用压缩则是压缩数据)以字节为单位的长度。


3.3.4 SSL告警协议
SSL报警协议是用来为对等实体传递SSL的相关警告。如果在通信过程中某一方发现任何异常,就需要给对方发送一条警示消息通告。警示消息有两种:
1. Fatal错误,如传递数据过程中发现错误的MAC,双方就需要立即中断会话,同时消除自己缓冲区相应的会话记录。
2. Warning消息,这种情况,通信双方通常都只是记录日志,而对通信过程不造成任何影响。SSL握手协议可以使得服务器和客户能够相互鉴别对方,协商具体的加密算法和MAC算法以及保密密钥,用来保护在SSL记录中发送的数据。
四、参考
RFC 5246 - The Transport Layer Security (TLS) Protocol Version 1.2
SSL/TLS协议详解 | 曹世宏的博客
SSL (Secure Sockets Layer)
SSL (Secure Sockets Layer)

    推荐阅读