关注网络安全
和行业未来

Cloutflare:TLS 1.3解读 你想了解的都在这儿

在过去的五年中,互联网工程任务组(IETF),即定义互联网协议的标准机构,一直致力于标准化其最重要的安全协议之一的最新版本:传输层安全性(TLS)。 TLS用于保护Web(以及更多!),提供加密并确保每个HTTPS网站和API的真实性。 最新版本的TLS,TLS 1.3(RFC 8446)于本月10日发布。 这是该协议的第一次重大改革,带来了重大的安全性和性能改进。 本文转载自Cloudflare博客,深入探讨了TLS 1.3中引入的变化及其对互联网安全未来的影响。

一场变革

Cloudflare提供安全性的一个主要方式是支持网站和API等Web服务的HTTPS。使用HTTPS(“S”代表安全),浏览器和服务器之间的通信通过加密和经过身份验证的通道传输。通过HTTPS而不是HTTP提供内容可以让访问者确信他们看到的内容是由合法内容所有者呈现的,并且通信是安全的,不会被窃听。在这个世界里,在线隐私比以往任何时候都更加重要,这是一个大问题。

使HTTPS安全的引擎下的机制是一种称为TLS的协议。它源于九十年代中期在Netscape开发的称为安全套接字层(SSL)的协议。到20世纪90年代末,Netscape将SSL交给IETF,IETF将其重命名为TLS,并从此成为该协议的管理者。许多人仍将Web加密称为SSL,即使绝大多数服务已切换到仅支持TLS。 SSL这个术语继续受到人们的欢迎,而Cloudflare通过无钥匙SSL和通用SSL等产品名称使这个术语保持活力。

在IETF中,协议称为RFC。 TLS 1.0是RFC 2246,TLS 1.1是RFC 4346,TLS 1.2是RFC 5246.今天,TLS 1.3发布为RFC 8446. RFC通常按顺序发布,保留46作为RFC编号的一部分是一个很好的延续。

在过去几年中,TLS已经被发现诸多的问题。 首先,实现TLS的代码存在问题,包括Heartbleed,BERserk,goto fail;等等。 这些问题不是协议的基础,而且主要是由于缺乏测试。 像TLS Attacker和Project Wycheproof这样的工具有助于提高TLS实施的稳健性,但TLS面临的更具挑战性的问题与协议本身有关。

TLS由工程师使用数学家的工具设计。 SSL时代的许多早期设计决策都是使用启发式方法和对如何设计健壮的安全协议的不完全理解。 也就是说,这不是协议设计者(Paul Kocher,Phil Karlton,Alan Freier,Tim Dierks,Christopher Allen等人)的错,因为整个行业仍在学习如何正确地做到这一点。 在设计TLS时,关于安全认证协议设计的正式论文,如Hugo Krawczyk的标志性SIGMA论文,还需要几年的时间。 TLS是90年代的密码:它当时意味着很好,看起来很酷,但是现代密码学家的调色板已经发展得不同了。

许多设计缺陷是使用形式验证发现的。 学者们试图证明TLS的某些安全属性,但却找到了反例,这些反例被转化为真正的漏洞。 这些弱点包括纯理论(SLOTH和CurveSwap),高资源攻击者(WeakDH,LogJam,FREAK,SWEET32),既“实用”又“危险”(POODLE,ROBOT)。

TLS 1.2实在是太慢了

加密在网上一直很重要,但从历史上看,它只用于登录或发送信用卡信息,使大多数其他数据暴露。 在过去几年中,一直存在一个主要趋势,即将HTTPS用于互联网上的所有流量。虽然能够保护更多我们在线上的交互,但却使连接变得更慢了。

要使浏览器和Web服务器就密钥达成一致,他们需要交换加密数据。 自TLS于1999年标准化以来,在TLS中称为“握手”的交换基本保持不变。握手需要在发送加密数据之前在浏览器和服务器之间再进行两次往返(或者在恢复先前连接时进行一次往返))。 与单独的HTTP相比,HTTPS的TLS握手的额外成本导致潜在的显着命中。 这种额外的延迟会对以性能为中心的应用产生负面影响。

定义TLS 1.3

IETF对TLS 1.2的过时设计和两次往返开销不满意,开始着手定义新版本的TLS。 2013年8月,Eric Rescorla为新协议制定了一份功能愿望清单:

https://www.ietf.org/proceedings/87/slides/slides-87-tls-5.pdf

经过一番辩论后,决定将这个新版本的TLS称为TLS 1.3。 推动TLS 1.3设计的主要问题与五年前提出的主要问题大致相同:

  • 减少握手延迟
  • 加密更多的握手
  • 提高跨协议攻击的弹性
  • 删除旧功能

该规范由志愿者通过开放的设计过程塑造,经过四年的勤奋工作和激烈的辩论,TLS 1.3现在处于最终形式:RFC 8446.随着采用的增加,新协议将使互联网更快、更安全。

下文将重点介绍TLS 1.3与以前版本相比的两个主要优势:安全性和性能。


在过去的二十年中,我们已经学到了很多关于如何编写安全加密协议的知识。 从POODLE到Lucky13到SLOTH到LogJam的巧妙命名攻击表明了,即使是TLS 1.2也包含了加密设计早期的陈旧观点。 TLS 1.3的设计目标之一是通过消除潜在危险的设计元素来纠正以前的错误。

修复密钥交换

TLS是所谓的“混合”密码系统。这意味着它使用对称密钥加密(加密和解密密钥相同)和公钥加密(加密和解密密钥不同)。混合方案是Internet上使用的主要加密形式,用于SSH,IPsec,Signal,WireGuard和其他协议。在混合密码系统中,公钥密码术用于在双方之间建立共享密钥,共享密钥用于创建可用于加密交换数据的对称密钥。

根据经验,公钥加密是缓慢且昂贵的(每个操作几微秒到几毫秒),对称密钥加密快速且便宜(每个操作纳秒)。混合加密方案允许您通过仅执行一次昂贵的部分,以极少的开销发送大量加密数据。 TLS 1.3中的大部分工作都是关于改进握手的部分,其中公钥用于建立对称密钥。

RSA密钥交换

TLS的公钥部分是关于建立共享秘密。 使用公钥加密有两种主要方法。 更简单的方法是使用公钥加密:一方用另一方的公钥加密共享密钥并发送它。 然后另一方使用其私钥解密共享秘密并且......原来他们都有同样的秘密。 这种技术于1977年由Rivest,Shamir和Adelman发现,称为RSA密钥交换。 在TLS的RSA密钥交换中,共享密钥由客户端决定,然后客户端将其加密到服务器的公钥(从证书中提取)并将其发送到服务器。

TLS中提供的另一种密钥交换形式是基于另一种形式的公钥密码术,由Diffie和Hellman于1976年发明,即所谓的Diffie-Hellman密钥协议。 在Diffie-Hellman中,客户端和服务器都从创建公钥 - 私钥对开始。 然后,他们将其关键份额的公共部分发送给另一方。 当每一方收到另一方的公钥共享时,他们将其与他们自己的私钥组合在一起,最终得到相同的值:前主秘密。 然后,服务器使用数字签名来确保交换未被篡改。 如果客户端和服务器都为每个交换选择一个新的密钥对,则该密钥交换称为“临时交换”。

两种模式都会导致客户端和服务器具有共享密钥,但RSA模式有一个严重的缺点:它不是前瞻性的。这意味着如果有人记录加密的对话,然后获得服务器的RSA私钥,他们就可以解密对话。这甚至适用于记录对话并且密钥在未来一段时间内获得的情况。在一个国家政府正在记录加密对话并使用像Heartbleed这样的漏洞来窃取私钥的世界中,这是一个相当现实的威胁。

RSA密钥交换在一段时间内一直存在问题,且不仅仅是因为它不是前向保密的。1998年,Daniel Bleichenbacher在SSL中进行RSA加密的方式发现了一个漏洞并创建了所谓的“百万消息攻击”,它允许攻击者通过发送一百万或者一个服务器的私钥来执行RSA私钥操作。 如此精心设计的消息,并寻找返回的错误代码的差异。 多年来,这种攻击得到了改进,在某些情况下只需要数千条消息便能从一台普通笔记本电脑发动攻击。最近发现,主要网站(包括facebook.com)在2017年也容易受到Bleichenbacher攻击变种的影响,称为ROBOT攻击。

为了降低非前向秘密连接和百万邮件攻击所带来的风险,RSA加密已从TLS 1.3中删除,将短暂的Diffie-Hellman作为唯一的密钥交换机制。 删除RSA密钥交换带来了其他优势,我们将在下面的性能部分中讨论。

以Diffie-Hellman命名的加密手段

在加密方面,提供太多选项会导致选择错误的选项。 在选择Diffie-Hellman参数时,这个原理最为明显。 在以前版本的TLS中,Diffie-Hellman参数的选择取决于参与者。 这导致一些实现选择不正确,导致部署易受攻击的实现。 TLS 1.3取消了这一选择。

Diffie-Hellman是一个功能强大的工具,但并非所有Diffie-Hellman参数都可以“安全”使用。 Diffie-Hellman的安全性取决于称为离散对数问题的特定数学问题的难度。 如果可以解决一组参数的离散对数问题,则可以提取私钥并破坏协议的安全性。 一般来说,使用的数字越大,解决离散对数问题就越困难。 因此,如果您选择较小的DH参数,则会遇到麻烦。

2015年的LogJam和WeakDH攻击表明,许多TLS服务器可能被欺骗使用Diffie-Hellman的小数字,允许攻击者破坏协议的安全性并解密对话。

Diffie-Hellman还要求参数具有某些其他数学属性。 2016年,Antonio Sanso在OpenSSL中发现了一个问题,其中选择的参数缺乏正确的数学属性,导致另一个漏洞。

TLS 1.3采用固定路由,将Diffie-Hellman参数限制为已知安全的参数。 但是,它仍然有几个选择; 只允许一个选项使得在以后发现这些参数不安全的情况下更新TLS非常困难。

混合加密方案的另一半是数据的实际加密。 这是通过组合认证码和对称密码来完成的,每个参与方都知道密钥。 正如我将要描述的,有许多方法可以加密数据,其中大多数都是错误的。

CBC模式密码

在上一节中,我们将TLS描述为混合加密方案,具有公钥部分和对称密钥部分。 公钥部分并不是多年来造成麻烦的唯一部分。 对称关键部分也有其公平的问题。 在任何安全通信方案中,您都需要加密(保密)和完整性(以确保人们不会修改,添加或删除对话的部分)。 对称密钥加密用于提供加密和完整性,但在TLS 1.2及更早版本中,这两个部分以错误的方式组合,导致安全漏洞。

执行对称加密和解密的算法称为对称密码。 对称密码通常有两种主要形式:分组密码和流密码。

流密码采用固定大小的密钥并使用它来创建任意长度的伪随机数据流,称为密钥流。 要使用流密码进行加密,您可以通过将密钥流的每个位与消息的相应位进行异或来获取消息并将其与密钥流合并。要解密,请使用加密消息并使用密钥流对其进行异或。 纯流密码的示例是RC4和ChaCha20。 流密码很受欢迎,因为它们易于实现且软件速度快。

分组密码与流密码不同,因为它只加密固定大小的消息。 如果要加密比块大小更短或更长的消息,则必须执行一些操作。 对于较短的消息,您必须在消息的末尾添加一些额外的数据。 对于较长的消息,您可以将消息拆分为密码可以加密的块,然后使用分组密码模式以某种方式将各个部分组合在一起。 或者,您可以通过使用块密码加密计数器序列并将其用作流来将块密码转换为流密码。 这称为“计数器模式”。 使用分组密码加密任意长度数据的一种流行方式是称为密码块链接(CBC)的模式。

为了防止人们篡改数据,加密是不够的。 数据还需要受到完整性保护。 对于CBC模式密码,这是使用称为消息验证代码(MAC)的东西来完成的,这类似于带有密钥的花哨校验和。 密码强的MAC具有以下特性:除非您知道密钥,否则找到与输入匹配的MAC值几乎是不可能的。 有两种方法可以组合MAC和CBC模式密码。 您先加密,然后加密密文,或者首先MAC明文,然后加密整个文件。 在TLS中,他们选择后者,MAC-then-Encrypt,结果证明是错误的选择。

你可以将这个选择归咎于BEAST,以及一系列填充oracle漏洞,例如Lucky 13和Lucky Microseconds。CBC模式和填充之间的交互也是SSLv3中广泛宣传的POODLE漏洞和TLS的一些实现的原因。

RC4是由Ron Rivest(RSA的“R”)设计的经典流密码,自TLS早期就得到广泛支持。 在2013年,它被发现具有可衡量的偏差,可以利用它来允许攻击者解密消息。

在TLS 1.3,所有麻烦的密码和密码模式已被删除。 您不能再使用CBC模式密码或不安全的流密码,如RC4。 TLS 1.3中允许的唯一类型的对称加密是一种称为AEAD(带有附加数据的经过身份验证的加密)的新结构,它将加密和完整性结合到一个无缝操作中。

修复数字签名

TLS的另一个重要部分是身份验证。 在每个连接中,服务器使用具有公钥的数字证书向客户端验证自身。 在RSA加密模式中,服务器通过解密预主密钥并在会话的记录上计算MAC来证明其对私钥的所有权。 在Diffie-Hellman模式下,服务器使用数字签名证明私钥的所有权。 如果你到目前为止都读得很仔细,应该很容易猜到这也是错误的。

PKCS#1v1.5

Daniel Bleichenbacher致力于识别TLS中RSA的问题。 2006年,他设计了针对TLS中使用的RSA签名的纸笔攻击。 后来发现包括NSS和OpenSSL在内的主要TLS实施容易受到这种攻击。 此问题再次与正确实现填充的难度有关,在这种情况下,RSA签名中使用的PKCS#1 v1.5填充。 在TLS 1.3中,删除了PKCS#1 v1.5以支持更新的设计RSA-PSS。

签署整个握手记录

我们之前描述过服务器如何使用数字签名来证明密钥交换没有被篡改。 在TLS 1.2及更早版本中,服务器的签名仅涵盖部分握手。 握手的其他部分,特别是用于协商使用哪个对称密码的部分,不由私钥签名。 相反,使用对称MAC来确保握手未被篡改。 这种疏忽导致了许多备受瞩目的漏洞(FREAK,LogJam等)。 在TLS 1.3中,这些被阻止,因为服务器签署整个握手记录。

FREAK,LogJam和CurveSwap攻击利用了两件事:

  1. 许多浏览器和服务器仍然支持20世纪90年代故意弱密码(称为导出密码)的事实,
  2. 以及用于协商使用哪种密码的握手部分未经数字签名的事实。

这些攻击被称为降级攻击,它们允许攻击者强制两个参与者使用双方支持的最弱密码,即使支持更安全的密码也是如此。 在这种攻击方式中,犯罪者处于握手的中间,并将从客户端通告的服务器支持的密码列表更改为仅包含弱导出密码。 然后,服务器选择一个弱密码,攻击者通过暴力攻击计算出密钥,允许攻击者在握手时伪造MAC。 在TLS 1.3中,这种类型的降级攻击是不可能的,因为服务器现在签署了整个握手,包括密码协商。

用简化来改善性能

TLS 1.3是一个更加优雅和安全的协议,删除了上面列出的不安全功能。 这种对冲修剪允许简化协议,使其更容易理解,更快。

在以前版本的TLS中,主要的协商机制是密码组。 密码套件几乎涵盖了可以就连接进行协商的所有内容:

  • 支持的证书类型
  • 用于导出密钥的散列函数(例如,SHA1,SHA256,...)
  • MAC功能(例如,HMAC与SHA1,SHA256,...)
  • 密钥交换算法(例如,RSA,ECDHE,......)
  • 密码(例如,AES,RC4,......)
  • 密码模式(如果适用)(例如,CBC)

先前版本的TLS中的密码套已经发展成为巨大的字母汤。 常用密码套件的示例是:DHE-RC4-MD5或ECDHE-ECDSA-AES-GCM-SHA256。 每个密码套件由一个名为Internet Assigned Numbers Authority(IANA)的组织维护的表中的代码点表示。 每次引入新密码时,都需要将一组新的组合添加到列表中。 这导致代码点的组合爆炸,代表着参数的每一个有效选择。

TLS 1.3删除了许多这些遗留功能,允许在三个正交协商之间进行彻底拆分:

  • 密码+ HKDF哈希
  • 密钥交换
  • 签名算法

这种简化的密码套件协商和从根本上减少的协商参数集开辟了一种新的可能性。 这种可能性使得TLS 1.3握手延迟从两次往返降至仅一次往返,从而提供性能提升,确保TLS 1.3受欢迎并广泛采用。


建立与之前没有见过的服务器的新连接时,需要两次往返才能在连接上发送数据。 这在服务器和客户端在地理位置上彼此靠近的位置并不是特别明显,但是它可以在移动网络上产生很大的差异,其中延迟可以高达200ms,这对人来说是显而易见的。

1-RTT模式

TLS 1.3现在具有更简单的密码协商模型和一组减少的密钥协商选项(没有RSA,没有用户定义的DH参数)。 这意味着每个连接都将使用基于DH的密钥协议,并且服务器支持的参数很容易猜测(ECDHE使用X25519或P-256)。 由于这种有限的选择,客户端可以简单地选择在第一条消息中发送DH密钥共享,而不是等到服务器确认它愿意支持哪些密钥共享。 这样,服务器可以学习共享密钥并提前一次往返发送加密数据。 例如,Chrome的TLS 1.3实现会在第一条消息中向服务器发送X25519密钥共享。

在极少数情况下,服务器不支持客户端发送的密钥共享之一,服务器可以发送新消 HelloRetryRequest,让客户端知道它支持哪些组。 由于列表已被削减太多,预计这种情况不常发生。

0-RTT恢复

QUIC协议启发了进一步的优化。 它允许客户端将第一条消息中的加密数据发送到服务器,与未加密的HTTP相比,不会产生额外的延迟成本。 这是一大进步,一旦TLS 1.3被广泛部署,加密的网络肯定比以前更加快捷。

在TLS 1.2中,有两种方法可以恢复连接,会话ID和会话票证。 在TLS 1.3中,这些被组合以形成称为PSK(预共享密钥)恢复的新模式。 该想法是在建立会话之后,客户端和服务器可以导出称为“恢复主密钥”的共享秘密。 这可以使用id(会话ID样式)存储在服务器上,也可以通过仅为服务器知道的密钥(会话票据样式)加密。 此会话票证将发送到客户端并在恢复连接时进行兑换。

对于恢复的连接,双方共享恢复主密钥,因此除了提供前向保密之外,不需要密钥交换。 下次客户端连接到服务器时,它可以从上一个会话中获取秘密并使用它来加密应用程序数据以及会话票证发送到服务器。

0-RTT数据中没有交互性。 它由客户端发送,并由服务器使用,没有任何交互。 这对性能很有帮助,但需要付出代价:可重复性。 如果攻击者捕获发送到服务器的0-RTT数据包,他们可以重播它,并且服务器有可能接受它为有效。 这会产生有趣的负面后果。

危险重放数据的一个示例是在服务器上更改状态的任何内容。 如果增加计数器,执行数据库事务或执行任何具有永久效果的操作,将其放入0-RTT数据中是有风险的。

作为客户端,您可以尝试通过仅将“安全”请求放入0-RTT数据来防止这种情况。 在此上下文中,“安全”表示请求不会更改服务器状态。 在HTTP中,不同的方法应该具有不同的语义。 HTTP GET请求应该是安全的,因此浏览器通常只能通过在0-RTT中发送GET请求来保护HTTPS服务器免受重放攻击。 由于大多数页面加载以GET“/”开头,因此页面加载时间更快。

当在0-RTT中发送的数据用于状态改变请求时,问题开始发生。 为帮助防止此故障情况,TLS 1.3还包括会话票证中的经过时间值。 如果这种情况发生太大分歧,客户端要么接近光速,要么重播值。 在任何一种情况下,服务器都应该谨慎拒绝0-RTT数据。

可部署性

TLS 1.3与TLS 1.2及更早版本完全不同,但为了广泛部署,它必须向后兼容现有软件。 TLS 1.3从草案到最终发布花了这么长时间的原因之一是,一些现有的软件(即中间盒)与新的更改并没有很好地协调。 即使在线上可见的TLS 1.3协议的微小更改(例如消除冗余的ChangeCipherSpec消息,将版本从0x0303提升到0x0304)最终导致某些人的连接问题。

尽管未来的灵活性已经内置到TLS规范中,但是一些实现对如何处理未来的TLS版本做出了错误的假设。造成这种变化的现象称为骨化, 为了适应这些变化,TLS 1.3被修改为看起来很像TLS 1.2会话恢复(至少在线路上)。 这导致了更多功能性但不太美观的协议,也是您在线升级最广泛部署的协议之一所付出的代价。

结语

TLS 1.3是一种现代安全协议,使用正式分析等现代工具构建,保持其向后兼容性。 它已经过广泛测试,并在使用现实世界部署数据时进行了迭代。 它是一种更清晰,更快速,更安全的协议,可以在线成为事实上的双方加密协议。

发布TLS 1.3是一项巨大的成就。也是近日行业里最好的示例,它证明了通过修改20年前部署的遗留代码来改善人们互联网体验,是一件多么棒的事!TLS 1.3在过去三年中一直处于争论和分析中,现在已准备好迎接它的黄金时段。 欢迎你,RFC 8446!

 

稿源:Cloudflare博客

评论 抢沙发