SSL协议
SSL:Secure Sockets Layer,安全套接层,是一套网络通信安全协议,由网景公司(Netscape)在1994年设计创建的,具有数据加密、完整性校验及身份验证等功能,目的是为互联网通信提供安全及数据完整性保障。SSL协议位于应用层与传输层之间,可以为任何基于TCP等可靠连接的应用层协议提供安全性保证。
TLS:Transport Layer Security,传输层安全性协议。 IETF将SSL进行标准化,1999年公布第一版TLS标准文件。随后又公布RFC 5246 (2008年8月)与RFC 6176(2011年3月)。用于在两个通信应用程序之间提供保密性和数据完整性,在浏览器、邮箱、即时通信、VoIP、网络传真等应用程序中,广泛支持这个协议。主要的网站,如Google、Facebook等也以这个协议来创建安全连线,发送数据。目前已成为互联网上保密通信的工业标准。
SSL/TLS协议主要用于提高应用程序之间数据的安全性,为TCP/IP连接提供数据加密、服务器认证、消息完整性以及可选的客户机认证。SSL可以和应用层的http协议配合形成https,也可以保证邮件协议的安全。当前版本为3.0。该安全协议主要提供对用户和服务器的认证;对传送的数据进行加密和隐藏;确保数据在传送中不被改变。它能使客户一服务器应用之间的通信不被攻击者窃听。SSL协议提供的服务主要有:
1)鉴别机制:认证用户和服务器,确保数据发送到正确的客户机和服务器;
2)保护隐私:加密数据以防止数据中途被窃取;
3)数据完整性:确保数据在传输过程中不被改变。
1、SSL协议结构
安全套接层协议SSL:SSL/TLS位于传输层和应用层之间,可以细分为两个子层,分别是SSL记录协议层、SSL握手协议层。 SSL记录协议层:主要的作用是进行数据的封装,压缩,加密等;SSL握手协议层:主要的作用是进行通信双方的身份认证,秘钥管理协商等。
从体系结构图可以看出SSL安全协议实际是SSL握手协议、SSL修改密文协议、SSL警告协议和SSL记录协议组成的一个协议族。
SSL记录协议为SSL连接提供了两种服务:一是机密性,二是消息完整性。为了实现这两种服务,SSL记录协议接收传输的应用报文,将数据分片成可管理的块,进行数据压缩(可选),应用MAC(校验消息),接着利用IDEA、DES、3DES或其他加密算法进行数据加密,最后增加由内容类型、主要版本、次要版本和压缩长度组成的首部。被接收的数据刚好与接收数据工作过程相反,依次被解密、验证、解压缩和重新装配,然后交给更高级用户。
SSL记录协议主要用来实现对数据块的分块、加密解密、压缩与解压缩、完整性检查及封装各种高层协议。SSL记录协议工作原理--将消息分割为多个片段;对每个片段进行压缩;加上片段编号(防止重放攻击)计算消息验证码MAC值(保证数据完整性),追加在压缩片段;对称密码加密;加上数据类型、版本号、压缩后的长度组成的报头, 就是最终的报文数据;
SSL修改密文协议是使用SSL记录协议服务的SSL高层协议的3个特定协议之一,也是其中最简单的一个。协议由单个消息组成,该消息只包含一个值为1的单个字节。该消息的唯一作用就是使未决状态拷贝为当前状态,更新用于当前连接的密码组。为了保障SSL传输过程的安全性,双方应该每隔一段时间改变加密规范。
SSL报警协议是用来为通信的对方传递SSL的相关警告。如果在通信过程中某一方发现任何异常,就需要给对方发送一条警示消息通告。警示消息有两种:一种是Fatal错误,如传递数据过程中,发现错误的MAC,双方就需要立即中断会话,同时消除自己缓冲区相应的会话记录;第二种是Warning消息,这种情况,通信双方通常都只是记录日志,而对通信过程不造成任何影响。SSL握手协议可以使得服务器和客户能够相互鉴别对方,协商具体的加密算法和MAC算法以及保密密钥,用来保护在SSL记录中发送的数据。
SSL握手协议允许通信实体在交换应用数据之前协商密钥的算法、加密密钥和对客户端进行认证的协议,为下一步记录协议要使用的密钥信息进行协商,使客户端和服务器建立并保持安全通信的状态信息。SSL握手协议是在任何应用程序数据传输之前使用的。SSL握手协议包含四个阶段:第一个阶段建立安全能力;第二个阶段服务器鉴别和密钥交换;第三个阶段客户鉴别和密钥交换;第四个阶段完成握手协议。
2、SSL协议的特性
SSL提供了两台机器间的安全连接。支付系统通过在SSL连接上传输信用卡卡号的方式来构建,在线银行和其他金融系统也常常构建在SSL之上。大部分Web浏览器和Web服务器都内置了SSL协议,比较容易应用。SSL协议建立在可靠的传输层协议(如TCP)之上,与应用层协议无关。它在应用层协议通信之前就已经完成加密算法、通信密钥的协商以及服务器认证工作。高层的应用层协议(如HTTP,FTP,TELNET等)可以透明地建立于SSL协议之上。应用层协议所传送的数据都会被加密,从而保证通信的私密性。SSL协议提供的安全信道有以下三种特性:
私密性:在握手协议定义了会话密钥后,所有的消息都被加密。
确认性:尽管会话的客户端认证是可选的,但是服务器端始终是被认证的。
可靠性:传送的消息包括消息完整性检查。
3、SSL的会话与连接
1)SSL连接:用于提供某种类型的服务数据的传输,是一种点对点的关系。一般来说,连接的维持时间比较短暂,并且每个连接一定与某一个会话相关联。
2)SSL会话:是指客户和服务器之间的一个关联关系。会话通过握手协议来创建。它定义了一组安全参数。
一次会话过程通常会发起多个SSL连接来完成任务,例如一次网站的访问可能需要多个HTTP/SSL/TCP连接来下载其中的多个页面,这些连接共享会话定义的安全参数。这种共享方式可以避免为每个SSL连接单独进行安全参数的协商,而只需在会话建立时进行一次协商,提高了效率。
每一个会话(或连接)都存在一组与之相对应的状态,会话(或连接)的状态表现为一组与其相关的参数集合,最主要的内容是与会话(或连接)相关的安全参数的集合,用会话(或连接)中的加密解密、认证等安全功能的实现。在SSL通信过程中,通信算法的状态通过SSL握手协议实现同步。
根据SSL协议的约定,会话状态由以下参数来定义:
- (1)会话标识符:是由服务器选择的任意字节序列,用于标识活动的会话或可恢复的会话状态。
- (2)对方的证书:会话对方的X.509v3证书。该参数可为空。
- (3)压缩算法:在加密之前用来压缩数据的算法。
- (4)加密规约(Cipher Spec):用于说明对大块数据进行加密采用的算法,以及计算MAC所采用的散列算法。
- (5)主密值:一个48字节长的秘密值,由客户和服务器共享。
- (6)可重新开始的标识:用于指示会话是否可以用于初始化新的连接。
连接状态由以下参数来定义:
- (1)服务器和客户器的随机数:是服务器和客户为每个连接选择的用于标识连接的字节序列。
- (2)服务器写MAC密值:服务器发送数据时,生成MAC使用的密钥,长度为128 bit。
- (3)客户写MAC密值,服务器发送数据时,用于数据加密的密钥,长度为128 bit 。
- (4)客户写密钥:客户发送数据时,用于数据加密的密钥,长度为128 bit。
- (5)初始化向量:当使用CBC模式的分组密文算法是=时,需要为每个密钥维护初始化向量。
- (6)序列号:通信的每一端都为每个连接中的发送和接收报文维持着一个序列号。
4、建立SSL连接的具体步骤
建立SSL连接的过程其实就是服务端与用户互相认证以及通信密钥协商的过程:
服务器认证阶段:
1)客户端向服务器发送一个开始信息“Hello”以便开始一个新的会话连接;
2)服务器根据客户的信息确定是否需要生成新的主密钥,如需要则服务器在响应客户的“Hello”信息时将包含生成主密钥所需的信息;
3)客户根据收到的服务器响应信息,产生一个主密钥,并用服务器的公开密钥加密后传给服务器;
4)服务器恢复该主密钥,并返回给客户一个用主密钥认证的信息,以此让客户认证服务器。
用户认证阶段:
在此之前,服务器已经通过了客户认证,这一阶段主要完成对客户的认证。经认证的服务器发送一个提问给客户,客户则返回(数字)签名后的提问和其公开密钥,从而向服务器提供认证。
1. Client Hello,客户端发送报文,支持的协议、算法套件、随机数A、Session ID、扩展版本;
2. Server Hello,服务端发送报文,确定的协议、算法、随机数B、Session ID、扩展版本;
3. Server Certificate,服务端发送报文,服务端证书;
4. Client Cert Request,服务端发送报文,非必须,客户端证书请求;
5. Service Key Exchange,服务端发送报文,非必须,发送函数中所计算的Yb;
6. Service Hello Done,服务端发送报文,告知客户端Hello阶段结束;
7. Client Certificate,客户端发送报文,非必须,客户端证书;
8. Client Key Exchange,客户端发送报文,发送预主密钥;
9. Change Cipher Spec,客户端/服务端发送报文,通知之后的信息全部采用加密信息;
10. Encrypted Handshake Message,客户端/服务端发送报文,密钥验证报文;
11. Application Data,客户端/服务端发送报文,加密数据报文;
SSL的建立过程总共有13个包,第一次建立至少需要9个包。
ClientHello
握手第一步是客户端向服务端发送 Client Hello 消息,这个消息里包含了一个客户端生成的随机数 Random1、客户端支持的加密套件(Support Ciphers)和 SSL Version 等信息。
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压缩。
- 扩展包:
其他参数(如服务器名称,填充,支持的签名算法等)可以作为扩展名使用。
这些是客户端问候的一部分,如果已收到客户端问候,接下来就是服务器的确认,服务器将发送服务器问候。
收到客户端问候之后服务器必须发送服务器问候信息,服务器会检查指定诸如TLS版本和算法的客户端问候的条件,如果服务器接受并支持所有条件,它将发送其证书以及其他详细信息,否则,服务器将发送握手失败消息。
如果接受,第二步是服务端向客户端发送 Server Hello 消息,这个消息会从 Client Hello 传过来的 Support Ciphers 里确定一份加密套件,这个套件决定了后续加密和生成摘要时具体使用哪些算法,另外还会生成一份随机数 Random2。注意,至此客户端和服务端都拥有了两个随机数(Random1+ Random2),这两个随机数会在后续生成对称秘钥时用到。
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中。
- 压缩算法:
如果支持,服务器将同意客户端的首选压缩方法。
- 扩展包
第一阶段之后,客户端服务端知道了下列内容:
- SSL版本
- 密钥交换、信息验证和加密算法
- 压缩方法
- 有关密钥生成的两个随机数。
SSL建立第二阶段:
服务器向客户端发送消息,服务器启动SSL握手第2阶段,是本阶段所有消息的唯一发送方,客户机是所有消息的唯一接收方。该阶段分为4步:
- 证书:服务器将数字证书和到根CA整个链发给客户端,使客户端能用服务器证书中的服务器公钥认证服务器。
- 服务器密钥交换(可选):这里视密钥交换算法而定
- 证书请求:服务端可能会要求客户自身进行验证。
- 服务器握手完成:第二阶段的结束,第三阶段开始的信号
Certificate消息—第一次建立必须要有证书
一般情况下,除了会话恢复时不需要发送该消息,在SSL握手的全流程中,都需要包含该消息。消息包含一个X.509证书,证书中包含公钥,发给客户端用来验证签名或在密钥交换的时候给消息加密。
这一步是服务端将自己的证书下发给客户端,让客户端验证自己的身份,客户端验证通过后取出证书中的公钥。
Server Key Exchange(可选)
根据之前在ClientHello消息中包含的CipherSuite信息,决定了密钥交换方式(例如RSA或者DH),因此在Server Key Exchange消息中便会包含完成密钥交换所需的一系列参数。
Certificate Request(可选)------可以是单向的身份认证,也可以双向认证
这一步是可选的,如果在对安全性要求高的常见可能用到。服务器用来验证客户端。服务器端发出Certificate Request消息,要求客户端发他自己的证书过来进行验证。该消息中包含服务器端支持的证书类型(RSA、DSA、ECDSA等)和服务器端所信任的所有证书发行机构的CA列表,客户端会用这些信息来筛选证书。
该消息表示服务器已经将所有信息发送完毕,接下来等待客户端的消息。
SSL建立第三阶段:
客户端收到服务器发送的一系列消息并解析后,将本端相应的消息发送给服务器。
客户机启动SSL握手第3阶段,是本阶段所有消息的唯一发送方,服务器是所有消息的唯一接收方。该阶段分为3步:
- 证书(可选):为了对服务器证明自身,客户要发送一个证书信息,这是可选的,在IIS中可以配置强制客户端证书认证。
- 客户机密钥交换(Pre-master-secret):这里客户端将预备主密钥发送给服务端,注意这里会使用服务端的公钥进行加密。
- 证书验证(可选),对预备秘密和随机数进行签名,证明拥有(a)证书的公钥。
Certificate(可选)
如果在第二阶段服务器端要求发送客户端证书,客户端便会在该阶段将自己的证书发送过去。服务器端在之前发送的Certificate Request消息中包含了服务器端所支持的证书类型和CA列表,因此客户端会在自己的证书中选择满足这两个条件的第一个证书发送过去。若客户端没有证书,则发送一个no_certificate警告。
根据之前从服务器端收到的随机数,按照不同的密钥交换算法,算出一个pre-master,发送给服务器,服务器端收到pre-master算出main master。而客户端当然也能自己通过pre-master算出main master。如此以来双方就算出了对称密钥。
如果是RSA算法,会生成一个48字节的随机数,然后用server的公钥加密后再放入报文中。如果是DH算法,这是发送的就是客户端的DH参数,之后服务器和客户端根据DH算法,各自计算出相同的pre-master secret.
本消息在给服务器发送的过程中,使用了服务器的公钥加密。服务器用自己的私钥解密后才能得到pre-master key.(向服务器证明自己的确持有客户端证书私钥。)
只有在客户端发送了自己证书到服务器端,这个消息才需要发送。其中包含一个签名,对从第一条消息以来的所有握手消息的HMAC值(用master_secret)进行签名。
完成握手协议,建立SSL连接。
客户机启动SSL握手第4阶段,使服务器结束。该阶段分为4步,前2个消息来自客户机,后2个消息来自服务器。
建立起一个安全的连接,客户端发送一个Change Cipher Spec消息,并且把协商得到的CipherSuite拷贝到当前连接的状态之中。然后,客户端用新的算法、密钥参数发送一个Finished消息,这条消息可以检查密钥交换和认证过程是否已经成功。其中包括一个校验值,对客户端整个握手过程的消息进行校验。服务器同样发送Change Cipher Spec消息和Finished消息。握手过程完成,客户端和服务器可以交换应用层数据进行通信。
编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送(ChangeCipherSpec是一个独立的协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到之前协商好的加密套件(Cipher Suite)的状态,准备使用之前协商好的加密套件加密数据并传输了)。
客户端握手结束通知, 表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验(使用HMAC算法计算收到和发送的所有握手消息的摘要,然后通过RFC5246中定义的一个伪函数PRF计算出结果,加密后发送。此数据是为了在正式传输应用数据之前对刚刚握手建立起来的加解密通道进行验证。)
服务端握手结束通知。
5、SSL会话恢复
会话恢复是指只要客户端和服务器已经通信过一次,它们就可以通过会话恢复的方式来跳过整个握手阶段二直接进行数据传输。
SSL采用会话恢复的方式来减少SSL握手过程中造成的巨大开销。为了加快建立握手的速度,减少协议带来的性能降低和资源消耗(具体分析在后文),SSL/TLS 协议有两类会话缓存机制:
- 会话标识 session ID:由服务器端支持,协议中的标准字段,因此基本所有服务器都支持,服务器端保存会话ID以及协商的通信信息,Nginx 中1M 内存约可以保存4000个 session ID 机器相关信息,占用服务器资源较多;
- 会话记录 session ticket:需要服务器和客户端都支持,属于一个扩展字段,支持范围约60%(无可靠统计与来源),将协商的通信信息加密之后发送给客户端保存,密钥只有服务器知道,占用服务器资源很少。
二者对比,主要是保存协商信息的位置与方式不同,类似与 http 中的 session 与 cookie。二者都存在的情况下,(nginx 实现)优先使用 session_ticket。
会话恢复具体过程(Session ID机制):
- 如果客户端和服务器之间曾经建立了连接,服务器会在握手成功后返回 session ID,并保存对应的通信参数在服务器中;
- 如果客户端再次需要和该服务器建立连接,则在 client_hello 中 session ID 中携带记录的信息,发送给服务器,消息中的会话ID 设置为计划重用的会话的ID。;
- 服务器根据收到的 session ID 检索缓存记录,如果没有检索到货缓存过期,则按照正常的握手过程进行; SSL服务器如果允许重用该会话,则通过在Server Hello消息中设置相同的会话ID来应答。这样,SSL客户端和SSL服务器就可以利用原有会话的密钥和加密套件,不必重新协商。
- 服务器如果检索到对应的缓存记录,则返回 change_cipher_spec 与 encrypted_handshake_message 信息,两个信息作用类似,encrypted_handshake_message 是到当前的通信参数与 master_secret的hash 值; 通知SSL客户端后续报文将采用原有会话的密钥和加密套件进行加密和MAC计算。
- SSL服务器计算已交互的握手消息的Hash值,利用原有会话的密钥和加密套件处理Hash 值,并通过Finished消息发送给SSL客户端,以便SSL客户端判断密钥和加密套件是否正确。
- 如果客户端能够验证通过服务器加密数据,则客户端同样发送 change_cipher_spec 与 encrypted_handshake_message 信息; SSL 客户端计算已交互的握手消息的Hash 值,利用原有会话的密钥和加密套件处理Hash值,并通过Finished消息发送给SSL服务器,以便SSL服务器判断密钥和加密套件是否正确。
- 服务器验证数据通过,则握手建立成功,开始进行正常的加密数据通信。
Session id会话复用有2个缺点:
服务器会大量堆积会话,特别是在实际使用时,会话老化时间配置为数小时,这种情况对服务器内存占用非常高。
如果服务器是集群模式搭建,那么客户端和A各自保存的会话,在合B尝试会话复用时会失败。
会话恢复具体过程( session ticket):
- 如果客户端和服务器之间曾经建立了连接,服务器会在 new_session_ticket 数据中携带加密的 session_ticket 信息,客户端保存;服务器在握手过程中,如果支持session ticket,则发送New session ticket类型的握手报文,其中包含了能够恢复包括主密钥在内的会话信息,当然,最简单的就是只发送master key。为了让中间人不可见,这个session ticket部分会进行编码、加密等操作;客户端收到这个session ticket,就把当前的master key和这个ticket组成一对键值保存起来。服务器无需保存任何会话信息,客户端也无需知道session ticket具体表示什么。
- 如果客户端再次需要和该服务器建立连接,则在 client_hello 中扩展字段 session_ticket 中携带加密信息,一起发送给服务器; 会在client hello的拓展中加上session ticket,然后服务器收到session ticket后,进行解密、解码能相关操作,来恢复会话信息。如果能够恢复会话信息,那么就会提取会话信息的主密钥进行后续的操作,服务器将按照会话复用流程,直接回复server hello,ccs,finished。
- 服务器解密 sesssion_ticket 数据,如果能够解密失败,则按照正常的握手过程进行;
- 如果解密成功,则返回 change_cipher_spec 与 encrypted_handshake_message 信息,两个信息作用与 session ID 中类似;
- 如果客户端能够验证通过服务器加密数据,则客户端同样发送 change_cipher_spec与encrypted_handshake_message 信息;
- 服务器验证数据通过,则握手建立成功,开始进行正常的加密数据通信。
6、SSL算法套件
- 身份验证+密钥协商/交换算法+批量加密算法+哈希算法
- 身份验证算法
- 密钥协商/交换算法
- 批量加密算法
- 哈希算法
7、SSL应用
HTTPs(其他应用层协议)
Openssl
应用安全网关
SSL VPN
参考: