网络信息安全|第2章:建立 SSL/TSL 安全连接

  • 原创
  • Madman
  • /
  • /
  • 0
  • 7660 次阅读

网络信息安全-min.jpg

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) 都是加密安全协议,它们用于确保网络通信安全,其主要目标是提供数据完整性和通信隐私。它位于应用层和传输层之间:

TLS place in network stack

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)的支持,删除了 IDEADES 等不再安全的密码套件,允许密码套件定义其自身的 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 算法缺少身份验证,所以还需要结合 RSAECDSA 等身份验证算法一起使用),更多详细信息请参考我的上一篇文章的第 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 功能

密码套件 是加密算法的组合,TLS v1.2 的每一组密码套件由 4 个部分组成: 密钥交换算法、身份验证算法、加密算法(加密握手结束消息和后续的会话消息)、MAC算法(检查整个握手消息和会话消息的完整性)

TLS 1.2 密码套件

注意: 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 握手

RSA版本TLS 1.2 握手

💖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.5
  • Cipher 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 将创建新会话并返回会话 ID
  • Selected 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:

没有双方共用的加密算法 02

💎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 RandomServer RandomPre-Master Secret,通过 伪随机函数(pseudorandom function,PRF) 生成 Master Secret(PRF 由双方选择的密码套件中指定):

master_secret = PRF(pre_master_secret, "master secret", client_random + server_random) [0..47];

最后又用 PRF 生成包含 6 个密钥的密钥块:

key_block = PRF(master_secret, "key expansion", client_random + server_random)
  • 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 RandomServer RandomPre-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 版本握手的模拟图:

RAS TLS 模拟对话图

另外,这种握手的过程中,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,接下来的握手阶段跟上图一样

Keyless-TLS-RSA

RSA 版本的 TLS 握手有个很大的缺点,握手阶段没办法加密,假设攻击者(运营商劫持)记录了这次握手的整个过程(他会知道通信双方选择的密码套件是什么,以及 Client Random 和 Server Random)和随后用 Session Key 对称加密通信的完整过程。那么此次会话数据的安全,就只取决于第三个随机数 Pre-Master Secret 能不能被破解

如果随后 Server 的私钥被攻击者盗取了(比如利用 Heartbleed

  • 6689711
  • 60971625
  • 48407630
  • 6592119771
  • alwayne
  • sandria
  • bertrum
  • 1415013
  • aleeksandr
  • zhang-3697789530
  • joeray
  • wahneta
  • jalijah
  • 145892774
  • tenara
  • aggie
  • avetik
  • abubakr
  • suvanna
  • jayko
  • megangot
  • catherin
  • iyanna
  • tekken
未经允许不得转载: LIFE & SHARE - 王颜公子 » 网络信息安全|第2章:建立 SSL/TSL 安全连接

分享

作者

作者头像

Madman

如需 Linux / Python 相关问题付费解答,请按如下方式联系我

0 条评论

暂时还没有评论.

专题系列