网络信息安全|第2章:建立 SSL/TSL 安全连接
Synopsis: 要了解 SSL 或 TLS 协议的工作原理,您必须首先了解第 1 章的加密与解密等基本概念。SSL/TLS 的安全实现用到了多种加密算法的组合,用非对称加密实现身份认证和密钥交换,用对称加密实现数据的加密传输,用单向加密检查数据的完整性。本文图文并茂地讲述了 TLS v1.2 基于 RSA 或 Diffie-Hellman 两种不同的握手,最后简述了去年发布的 TLS 1.3 版本,它在安全性和性能方面都有了很大的改进,目前像 Google、Github 等都已经在使用 TLS 1.3 了
1. 什么是 SSL/TLS
安全套接字层(SSL,Secure Sockets Layer)
和 传输层安全性(TLS,Transport Layer Security)
都是加密安全协议,它们用于确保网络通信安全,其主要目标是提供数据完整性和通信隐私。它位于应用层和传输层之间:
SSL
协议最初由 Netscape 公司于 1994 年推出,SSL 1.0 版本从未发布,因为它存在严重的安全漏洞。SSL 的第一个正式版本 2.0 版本于 1995 年发布,SSL 协议的最终版本 SSL 3.0 于 1996 年 11 月发布
由于互联网的蓬勃发展,越来越多的用户意识到数据安全传输的重要性。1999 年 1 月,互联网工程任务组(IETF,Internet Engineering Task Force)
标准化了一种名为 TLS
的新协议,作为 SSL v3 的修订版本。TLS 1.0 RFC 文档(RFC 2246) 说明了 TLS 1.0 与 SSL 3.0 的区别并不大,因此 TLS 1.0 也可以称为 SSL 3.1。TLS 1.1(RFC 4346)是 TLS 1.0 的一个小更新,于 2006 年 4 月发布。TLS 1.2(RFC 5246)于 2008 年 8 月发布,它添加对已验证的加密算法(比如 AES
)的支持,添加对 HMAC-SHA256
密码套件(cipher suite)的支持,删除了 IDEA
和 DES
等不再安全的密码套件,允许密码套件定义其自身的 PRF
2011 年,IETF
宣布弃用 SSL 2.0 版本,RFC 6176 文档指出了 SSL 2.0 存在的几个主要缺陷。2015 年 6 月,IETF
还宣布弃用 SSL 3.0 版本。正如 RFC 7568 文档中所述,任何 TLS 版本都比所有版本的 SSL 更安全,现代浏览器(比如 Chrome 或 Firefox )都使用 TLS
。建议: 你应该在服务端禁止使用 SSL
协议,仅开启 TLS
协议
简而言之,TLS
协议是 SSL
协议的后继版本,由于 TLS 是 SSL 协议的演变,所以人们仍然可以互换使用术语 TLS 和 SSL
当前最新版本的 TLS 1.3 于 2018 年 8 月发布(RFC 8446),简化了 TLS Handshake
,握手现在只需要一次往返,以获得更好的性能
2. 安全目标
TLS
要保障互联网安全通信的话,就必须实现三个至关重要的目标: 身份验证、数据机密性和数据完整性
身份验证
可以确保通信的另一端确实是他们所说的人,而不是攻击者所冒充的。上一篇 文章的第 5 章说过我们可以通过 公钥加密
来实现身份认证,同时为保证公钥是可信的,对端需要提供由受信 CA 签名的 数字证书
(证明证书是可信的),对端随后还需要证明自己是证书的所有者(持有对应的私钥),更多详细信息请参考我的上一篇文章的第 7 章
当通信双方确认没有其它人能够理解他们的会话消息时,那么通信被认为是保密的。我们可以使用 对称加密
实现机密性(因为 对称加密
比 公钥加密
能更有效地实现强加密): 在发送会话消息之前,使用只有通信双方才知道的密钥(会话密钥,Session key
)对消息进行加密。在 TLS
中,对称加密
通常使用像 AES
这样的强分组密码来完成,可能较旧的浏览器和平台还在使用分组密码 Triple DES
或流密码 RC4
,目前已证明它们是不安全的对称加密算法,所以请停止使用它们,更多详细信息请参考我的上一篇文章的第 2 章。数据加密后,还需要保证数据在传输过程中不会被篡改或损坏,我们可以通过 单向加密
来确保数据的完整性,更多详细信息请参考我的上一篇文章的第 4 章
关于如何生成用于对称加密的 会话秘钥
,并安全地进行 密钥交换
,可以使用对端的 公钥
加密此会话密钥,那么只有真正持有对端的 私钥
的人才能解密并获取到会话密钥。或者,采用 Diffie-Hellman 密钥交换
算法,双方只需要交换 DH 参数,然后各自就可以生成同样的会话密钥(但是由于 DH
算法缺少身份验证,所以还需要结合 RSA
或 ECDSA
等身份验证算法一起使用),更多详细信息请参考我的上一篇文章的第 6 章
说明:
TLS
在建立连接时,通过一系列称为握手(Handshake)
的过程来实现上述安全目标
3. TLS v1.2 Handshake
TLS
v1.2 版本(以及之前的版本)有两种主要的握手方式: 一种基于 RSA
,另一种基于 Diffie-Hellman 密钥交换
。TLS v1.3 简化了握手过程,本文章节 4 将详述
密钥交换(Key exchange) | 身份认证(Authentication) | |
---|---|---|
基于 RSA 握手 | RSA |
RSA |
基于 DH 握手 | DH /DHE /ECDH /ECDHE |
RSA /DSA /EdDSA /ECDSA |
由于通信双方(比如浏览器和 Web 服务器)所支持的 TLS
版本不一定相同,而且所支持的 密码套件(Cipher Suites)
也不尽相同,所以它们首先需要就加密方法达成一致。要查看客户端浏览器支持的 SSL/TLS 功能,可以访问: https://www.ssllabs.com/ssltest/viewMyClient.html
密码套件
是加密算法的组合,TLS v1.2 的每一组密码套件由 4 个部分组成: 密钥交换算法、身份验证算法、加密算法(加密握手结束消息和后续的会话消息)、MAC算法(检查整个握手消息和会话消息的完整性)
注意:
GCM
套件支持 AEAD,所以套件名称的最后一段用来指明所使用的PRF
函数,而非 MAC 算法
[root@CentOS ~]# openssl ciphers -v ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384 ...
比如 ECDHE-RSA-AES256-SHA384
表示:
ECDHE
: Elliptic Curve Diffie–Hellman Ephemeral,它是用于密钥交换的算法RSA
: 它是用于身份验证的算法AES256
: Advanced Encryption Standard 256 bit,它是对称加密算法,用于建立 TLS 连接后(完成握手阶段)加密双方的会话消息SHA384
: Secure Hash Algorithm 384 bit,它是Message Authentication Code (MAC)
算法,用于检查消息的完整性
3.1 RSA 版本
下图示例基于 Web 浏览器握手,但这同样适用于其他的所有 SSL/TLS 握手
💖1. Client Hello(Client -> Server)
: 首先 Client 会发送 Client Hello
消息给 Server,此消息包含:
Protocol Version
: TLS 1.2(0x0303),因为 TLS 1.0 是 SSL 3.0 的修订版,所以 TLS 1.0 用3,1
表示,TLS 1.1 用3,2
表示,TLS 1.2 用3,3
表示Client Random
: Client 产生 32 字节的随机数据,用于后续握手过程中产生共享密钥Session ID
: Client 可以提供针对此 Server 的先前 TLS 会话的 ID,该 Server 可以搜索它的会话列表恢复会话。为此,Client 和 Server 都需要记住内存中先前连接的密钥信息。恢复连接可以节省大量计算和网络往返时间,详情见本文的章节 3.5Cipher Suites
: Client 提供它支持的密码套件列表(按优先级从高到低排列),每个密码套件都指定了用于密钥交换算法、签名算法、对称加密算法和 MAC 算法Compression Methods
: Client 支持的压缩方法,默认是 null 代表不启动压缩。压缩有 风险 ,建议不要使用Extensions List
: Client 提供了可选扩展的列表(比如 Extension: signature_algorithms),Server 可以使用该扩展来执行操作或启用新功能
💎2. Server Hello(Server -> Client)
: Server 会回复 Server Hello
消息,此消息包含:
Selected Protocol Version
: TLS 1.2(0x0303)Server Random
: Server 产生 32 字节的随机数据,用于后续握手过程中产生共享密钥Session ID
: 如果 Client 没有指明要恢复的会话,Server 将创建新会话并返回会话 IDSelected Cipher Suite
: Server 从 Client 给出的密码套件列表中选择双方共有的一个密码套件,比如TLS_RSA_WITH_AES_128_GCM_SHA256
Selected Compression Method
: 一般不执行压缩Extensions List
: 比如 Extension: session_ticket
如果 Client 支持的密码套件与 Server 没有任何共同的,此次握手就会失败:
用 Wireshark 抓包,Client 在发出 Client Hello
后会收到 Server 发来的 Alert:
💎3. Certificate(Server -> Client)
: Server 发送 证书链
(Server 自己的 数字证书
和中间 CA 证书,但不包含 CA 根证书)
💎4. Server Hello Done(Server -> Client)
: Server 将此消息发送给 Client,以确认 Server Hello
消息已完成
💖5. Client 验证 证书链
,检查 Server 的 数字证书
上的 数字签名
(用 CA 的公钥解密,并核对证书的摘要是否一致),检查证书是否在有效期内,检查证书是否被吊销(离线 CRL
或在线 OCSP
),检查证书的使用者信息(比如,CN 是否与当前访问的域名相匹配)
💖6. Client 产生随机数 Pre-Master Secret
,然后 Client 结合 Client Random
、Server Random
和 Pre-Master Secret
,通过 伪随机函数(pseudorandom function,PRF)
生成 Master Secret
(PRF 由双方选择的密码套件中指定):
最后又用 PRF 生成包含 6 个密钥的密钥块:
client_write_MAC_key
: 用于计算MAC
的密钥server_write_MAC_key
: 用于计算MAC
的密钥client_write_key
: 对称加密的密钥Session Key
server_write_key
: 对称加密的密钥Session Key
client_write_IV
: 对称加密算法有些模式需要初始向量 Initialization Vector (IV),比如AES-128-CBC
server_write_IV
: 对称加密算法有些模式需要初始向量 Initialization Vector (IV),比如AES-128-CBC
💖7. Client 用 Server 的数字证书中所包含的 Server 公钥加密 Pre-Master Secret
💖8. Client Key Exchange(Client -> Server)
: Client 将加密后的 Pre-Master Secret
发送给 Server
💖9. Change Cipher Spec(Client -> Server)
: Client 通知 Server 它已生成最终的 Session Key
,准备切换到加密通信
💖10. Encrypted Handshake Message(Client -> Server)
: 此步骤也可称为 Finished
,它指示 Client 已完成握手。Client 会用步骤 2 中 Server 选中的密码套件中的检查消息完整性的算法,生成此次握手的全部信息的 MAC(Message Authentication Code)
,并用步骤 6 生成的 Session Key
进行对称加密(用会话秘钥保护的第 1 个数据)。注意: TLS v1.2 使用 MtE(MAC then Encryption)
,事实证明不安全
💎11. Server 如果能用它的私钥解密出 Pre-Master Secret
,则达成两个目标: 双方安全地完成 密钥交换
; 证明 Server 确实持有对方的私钥,完成 身份验证
💎12. Server 结合 Client Random
、Server Random
和 Pre-Master Secret
也最终生成 Session Key
💎13. New Session Ticket(Server -> Client)
: (可选)如果 Server 端启用了 Session Ticket
功能,则需要将新建此次会话的 Session Ticket 发送给 Client,会话关闭后还可以通过 Session Ticket 重新恢复连接。如果 Server 没有启用此功能,会话关闭后默认可通过 Session ID 恢复
💎14. Change Cipher Spec(Server -> Client)
: Server 通知 Client 它已经拿到了 Pre-Master Secret
,也生成了最终的 Session Key
,准备切换到加密通信
💎15. Encrypted Handshake Message(Server -> Client)
: 此步骤也可称为 Finished
,它指示 Server 已完成握手。Server 先用步骤 12 中生成的 Session Key
解密出 Client 发过来的 MAC
,然后它再用同样的算法也计算出 MAC
,如果对比后一致,则可以确保整个握手阶段的消息没有被篡改
👑16. Encrypted Application Data(Client <---> Server)
: 双方使用同样的 Session Key
对称加密通信
RSA 版本的 TLS 握手中密钥交换和身份验证是同时发生的: 步骤 5 验证证书的合法性,步骤 11 可同时实现 密钥交换
和 身份验证
为加深理解,我们再来看一张 TLS RSA 版本握手的模拟图:
另外,这种握手的过程中,Server 的 私钥
只需要在步骤 11 使用一次,所以安全服务商 CloudFlare
可以实现如下 Keyless SSL/TLS (RSA)
服务,允许我们在地理位置上分割 TLS 握手: 假设银行客户为加速自己的官方网站的访问速度,可能会使用外部 CDN 服务,但出于安全考虑,银行不想将非对称加密的 私钥
也放到 CDN 中去。那么,银行可以选择 CloudFlare 的 CDN 服务,因为它可以实现 Keyless SSL/TLS
。Client 访问 CDN 开始 TLS 握手,CDN 在步骤 11 时需要 私钥
来解密出 Pre-Master Secret
,此时 CDN (CloudFare) 会通过已建立的安全通道,将密文发送给银行内网的 Key Server
(保存了私钥的服务器)去解密,然后它再将解密出来的 Pre-Master Secret
发送给 CDN,接下来的握手阶段跟上图一样
RSA 版本的 TLS 握手有个很大的缺点,握手阶段没办法加密,假设攻击者(运营商劫持)记录了这次握手的整个过程(他会知道通信双方选择的密码套件是什么,以及 Client Random 和 Server Random)和随后用 Session Key
对称加密通信的完整过程。那么此次会话数据的安全,就只取决于第三个随机数 Pre-Master Secret
能不能被破解
如果随后 Server 的私钥被攻击者盗取了(比如利用 Heartbleed
0 条评论
评论者的用户名
评论时间暂时还没有评论.