在过去的五年中,互联网工程任务组(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)。oracle
TLS 1.2实在是太慢了ide
加密在网上一直很重要,但从历史上看,它只用于登陆或发送信用卡信息,使大多数其余数据暴露。 在过去几年中,一直存在一个主要趋势,即将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参数时,这个原理最为明显。 在之前版本的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很是困难。
混合加密方案的另外一半是数据的实际加密。 这是经过组合认证码和对称密码来完成的,每一个参与方都知道密钥。 正如我将要描述的,有许多方法能够加密数据,其中大多数都是错误的。
在上一节中,咱们将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模式下,服务器使用数字签名证实私钥的全部权。 若是你到目前为止都读得很仔细,应该很容易猜到这也是错误的。
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攻击利用了两件事:
一、许多浏览器和服务器仍然支持20世纪90年代故意弱密码(称为导出密码)的事实,
二、以及用于协商使用哪一种密码的握手部分未经数字签名的事实。
这些攻击被称为降级攻击,它们容许攻击者强制两个参与者使用双方支持的最弱密码,即便支持更安全的密码也是如此。 在这种攻击方式中,犯罪者处于握手的中间,并将从客户端通告的服务器支持的密码列表更改成仅包含弱导出密码。 而后,服务器选择一个弱密码,攻击者经过暴力攻击计算出密钥,容许攻击者在握手时伪造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,这对人来讲是显而易见的。
TLS 1.3如今具备更简单的密码协商模型和一组减小的密钥协商选项(没有RSA,没有用户定义的DH参数)。 这意味着每一个链接都将使用基于DH的密钥协议,而且服务器支持的参数很容易猜想(ECDHE使用X25519或P-256)。 因为这种有限的选择,客户端能够简单地选择在第一条消息中发送DH密钥共享,而不是等到服务器确认它愿意支持哪些密钥共享。 这样,服务器能够学习共享密钥并提早一次往返发送加密数据。 例如,Chrome的TLS 1.3实现会在第一条消息中向服务器发送X25519密钥共享。
在极少数状况下,服务器不支持客户端发送的密钥共享之一,服务器能够发送新消 HelloRetryRequest,让客户端知道它支持哪些组。 因为列表已被削减太多,预计这种状况不常发生。
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!
【来自SSL中国】