路漫漫其修远兮
吾将上下而求索

keyless ssl原理

昨天我们公布了无钥匙SSL的绝对积极回应。我们阅读了这篇博客的评论,Reddit,Hacker News,人们似乎有兴趣了解更多信息,深入了解技术细节。在这篇博客文章中,我们进入了非常详细的回顾关于无钥匙SSL的设计,工作原理以及为什么安全的问题。在我们这样做之前,我们需要一些关于加密如何在互联网上工作的背景知识。如果您已经熟悉,请随时跳过。

TLS

传输层安全(TLS)是网络安全的主力。它允许网站向Web浏览器证明自己的身份,并通过加密来保护所有与窥探交流的信息。TLS协议已经存在多年了,但是即使是硬核技术爱好者,它仍然是神秘的。了解TLS的基本原理是了解无钥匙SSL的关键。

双目标

TLS有两个主要目标:保密性和认证。两者对于在互联网上安全通信至关重要。

当双方相信没有人能够理解他们的交谈时,沟通被视为保密。使用对称加密可以实现保密性:使用只有双方知道的密钥才能在发送消息之前加密消息。在TLS中,这种对称加密通常使用像AES这样的强块密码来完成。较老的浏览器和平台可能使用像三重DES或流密码RC4 这样的密码,现在被认为是不安全的。

TLS的另一个关键目标是认证。认证是确保另一方的人是他们说他们是谁的方式。这是用公钥完成的。网站使用证书和公钥加密来证明其与网络浏览器的身份。浏览器需要两件事来信任证书:证明对方是证书的所有者,证明证书是可信的。

网站证书包含公钥,如果网站可以证明其控制相关联的私钥,则证明他们是证书的所有者。如果证书是由受信任的证书颁发机构授予的,并且包含该站点的域名,则浏览器认为证书是可信的。关于信任如何与Web证书有关的更多技术细节在前面关于我们的开源SSL工具包CFSSL的博客文章中有所描述。

在网络的上下文中,通过建立共享密钥并证明证书的所有权的过程来实现机密性和认证。TLS通过一系列称为“握手”的消息来实现。

握手中有什么?

TLS协议从20世纪90年代中期由Netscape开发的安全套接层(SSL)协议演变而来。1999年,互联网工程任务组(IETF)标准化了一个称为TLS的新协议,这是SSL的更新版本。实际上,TLS与SSL类似,TLS 1.0使用SSL协议版本号3.1。这可能看起来很混乱,但是很有道理,因为TLS只是对SSL 3.0的一个小的更新。TLS的后续版本遵循了此模式。由于TLS是SSL协议的演进,因此人们仍然可以使用术语TLS和SSL。

TLS中有两种主要类型的握手方式:一种基于RSA,一种基于Diffie-Hellman。RSA和Diffie-Hellman是迎来现代密码学时代的两种算法,将密码学带给了群众。这两个握手在仅仅实现密钥建立和认证的两个目标方面有所不同:

RSA和DH握手都有其优点和缺点。RSA握手只使用一个公钥算法操作RSA。使用RSA证书的DH握手需要相同的RSA操作,但需要额外的DH操作。鉴于证书是RSA,RSA握手速度更快。公共密钥算法(如RSA和DH)使用了大量的CPU,是TLS握手中最慢的部分。一台笔记本电脑每秒只能执行一百个RSA加密,每秒约对1000万个对称密码AES。

DH握手需要运行两种算法,但是它带来的优点是它允许密钥建立独立于服务器的私钥发生。这给了连接前进保密,这是一个有用的属性,保护对话在事实之后被解密,如果私钥以某种方式暴露出来。DH版本的握手还打开了使用可以提高性能的非RSA证书(包括ECDSA密钥)的可能性。椭圆曲线提供相同的安全性,减少计算开销。DH握手与椭圆曲线DSA证书和椭圆曲线Diffie-Hellman密钥协议可以比单操作RSA握手更快。

CloudFlare支持握手功能,但是我们稍后将会介绍,所使用的握手类型是由服务器选择的。CloudFlare会随时选择DH握手。

TLS术语表

在我们走过握手的步骤之前,这里有几个定义。

1.会话密钥 这是握手的最终结果。它是对称密码的关键,并允许客户端和服务器彼此加密消息。

2.客户端随机 这是由客户端创建的32个字节的序列。它对于每个连接是唯一的,并且应该包含四个字节的时间戳,后跟28个随机字节。最近,谷歌Chrome切换到使用32字节的随机,以防止客户端指纹。这些随机值通常称为随机数。

3.服务器随机 服务器随机与服务器生成的随机服务器相同。

4.前主密码 这是一个48字节的数据块。它可以与客户端随机和服务器随机组合,以使用“伪随机函数”(PRF)创建会话密钥。

5.密码套件 这是组合TLS 连接的算法的唯一标识符。它为以下各项定义了一种算法:

        密钥建立(通常是Diffie-Hellman变体或RSA)

        认证(证书类型)

        保密性(对称密码)

        完整性(散列函数)

例如“AES128-SHA”定义了一个会话,它使用:

        密钥建立RSA(隐含)

        RSA认证(隐含)

        128位高级加密标准在密码块链接(CBC)模式对保密

        160位安全散列算法(SHA)完整性

一个更加令人生畏但却有效的加密套件是“ECDHE-ECDSA-AES256-GCM-SHA384”,它定义了一个会话:

        椭圆曲线Diffie-Hellman短暂(ECDHE)密钥交换密钥建立

        椭圆曲线数字签名算法(ECDSA)用于认证

        Galois / Counter模式(GCM) 256位高级加密标准,用于保密

        384位安全散列算法,用于完整性

有了这些定义,让我们走一个RSA握手。

RSA握手

请注意,握手中的消息都不会用会话密钥加密; 他们都是明文发送。

ssl_handshake_rsa.jpg

消息1:“客户端你好”

客户端hello包含客户端要使用的协议版本,以及一些其他信息来启动握手,包括客户端随机和密码套件列表。现代浏览器还包括他们正在寻找的主机名,称为服务器名称指示(SNI)。SNI允许Web服务器在同一IP地址上托管多个域。

消息2:“服务器你好”

服务器收到客户端后,会选择握手的参数。密码套件的选择决定了执行什么类型的握手。服务器“hello”消息包含服务器随机,服务器选择的加密套件和服务器的证书。证书包含服务器的公钥和域名。

注意:CloudFlare的密码套件首选项公开发布在我们的Github页面上。

消息3:“客户密钥交换”

验证证书是否被信任并且属于他们尝试访问的站点后,客户端将创建一个随机的预先密钥。该秘密使用公钥从证书加密,并发送到服务器。

收到此消息后,服务器将使用其私钥来解密此前主机密码。既然双方具有预先的秘密,客户端和服务器都是随机的,那么它们都可以导出相同的会话密钥。然后他们交换一个短消息,表示他们发送的下一个消息将被加密。

当客户端和服务器交换“已完成”消息时,握手正式完成。实际的文字是字面上:用会话密钥加密的“客户端完成”或“服务器完成”。双方之间的任何后续通信都使用会话密钥进行加密。

这种握手优雅,因为它将密钥交换和身份验证结合在一个步骤中。逻辑是,如果服务器可以正确地导出会话密钥,那么它们必须具有对私钥的访问权限,因此可以是证书的所有者。

这种握手的缺点在于,其保护的消息与私钥一样安全。假设第三方记录了握手和后续通信。如果该方将来可以访问私钥,他们将能够解密前端秘密并导出会话密钥。因此,他们可以解密整个消息。即使证书已过期或撤销也是如此。这导致我们进行另一种形式的握手,即使私钥被破坏也可以提供机密性。

短暂的Diffie-Hellman握手

短暂的Diffie-Hellman握手是TLS握手的另一种形式。它使用两种不同的机制:一种用于建立共享的前主机密码,另一种用于认证服务器。依赖的关键特征是Diffie-Hellman密钥协商算法。

在Diffie-Hellman中,具有不同秘密的双方交换信息以获得共享的秘密。这种握手依赖于指数是可交换的简单事实。具体来说,将一个数字代入一个的权力,并且对b的权力的结果与对b的权力取同一个数字,并且将结果赋予a的权力。

该算法的工作原理如下:

        一个人有秘密,发送摹一到某乙

        某乙有秘密B,发送g ^ b,以一个人

        人a计算(g b)a

        人b计算(g a)b

        人a和b最终都是g ab,这是他们的共同秘密

这对于常规数字来说不能正常工作,因为g ab可以变得非常大,并且有一种有效的方式来取代数字的第n个根。但是,我们可以改变问题空间并使其工作。这是通过将计算结果限制为大素数并取余数来计算固定大小的数字来完成的。这被称为模数运算。以模数运算为第n个根称为离散对数问题,被认为是一个难题。

Diffie-Hellman密钥协议的另一个变体使用椭圆曲线,ECDHE。有关椭圆曲线的更多信息,请查阅我们去年发布的这个引言。可以使用这些固定大小的Diffie-Hellman密钥协商算法中的任何一个导出共享秘密。

现在让我们通过一个Diffie-Hellman握手:

ssl_handshake_rsa.jpg

消息1:“客户端你好”

就像RSA一样,客户端hello包含协议版本,客户端随机,密码套件列表,以及可选的SNI扩展名。如果客户说ECDHE,它们包括他们支持的曲线列表。如果省略这一点,或者存在不匹配的话,可能会很难调试。

消息2:“服务器你好”

服务器收到客户端后,会选择握手的参数,包括ECDHE的曲线。服务器“hello”消息包含服务器随机,服务器选择的加密套件和服务器的证书。

在这一点上,RSA和Diffie-Hellman握手开始不同,新的消息类型。

消息3:“服务器密钥交换”

为了启动Diffie-Hellman密钥交换,服务器需要选择一些启动参数并将其发送给客户端 – 这对应于上面描述的g a。服务器还需要一种方式来证明它具有对私有密钥的控制,所以服务器计算到目前为止所有消息的数字签名。Diffie-Hellman参数和签名都在此消息中发送。

消息4:“客户密钥交换”

验证证书是否受信任,并且属于他们试图访问的站点时,客户端会验证从服务器发送的数字签名。他们还向客户发送了Diffie-Hellman握手的一半(对应于上述g b)。

在这一点上,双方可以从Diffie-Hellman参数(对应于上述g ab)计算出预先的秘密。使用预先主密钥,客户端和服务器随机,可以导出相同的会话密钥。然后他们交换一个短消息,表示他们发送的下一个消息将被加密。

就像在RSA握手中,当客户端和服务器交换“完成”消息时,这个握手正式完成。双方之间的任何后续通信都使用会话密钥进行加密。

使其无钥匙

昨天我们发布了无钥匙SSL,CloudFlare的解决方案,允许网站使用CloudFlare,而不需要放弃其私钥的保管。

上述握手图中的一个例外是私钥只能在每次握手中使用一次。这允许我们在地理上分割TLS握手,大多数握手在CloudFlare的边缘发生,同时将私钥操作移动到远程密钥服务器。该密钥服务器可以放在客户的基础架构上,让他们独占访问私钥。

安全隧道建立后,RSA握手如下所示:

cloudflare_keyless_ssl_handshake_rsa.jpg

DH握手看起来像这样:

cloudflare_keyless_ssl_handshake_diffie_hellman.jpg

以这种方式扩展TLS握手需要对NGINX服务器和OpenSSL进行更改,使私钥操作都能远程和非阻塞(因此NGINX可以在等待密钥服务器时继续其他请求)。NGINX / OpenSSL都改变了,CloudFlare的服务器和密钥服务器之间的协议由iSEC Partners和Matasano Security进行了审计。他们发现无钥匙SSL的安全性相当于内部部署SSL。学术研究人员从可靠的安全性和性能角度也研究了无钥匙SSL。

关键服务器可以在Linux上运行(针对Red Hat / CentOS,Debian和Ubuntu等),其他UNIX操作系统(包括FreeBSD)和Microsoft Windows Server。客户还可以访问一个参考实现用C写的,这样他们就可以建立自己的兼容密钥服务器。

关键服务器将很快与硬件安全模块(HSM)供应商和密钥管理解决方案(如Venafi)集成,为客户提供其他方法来控制密钥在其基础架构中的管理。

无钥匙SSL支持相同证书的多个密钥服务器。关键服务器是无状态的,允许客户使用现成的硬件,并按照流量线性地扩展关键服务器的部署。通过运行多个密钥服务器并通过DNS进行负载平衡,客户的站点可以保持高可用性。

保护神谕

保护Oracle

为了安全起见,从CloudFlare的边缘到密钥服务器的连接也需要安全。密钥服务器可以通过执行私人密钥操作来为任何可以联系的密码操作。确保只有CloudFlare可以要求密钥服务器执行操作对于无钥匙SSL的安全性至关重要。

我们通过相互认证的TLS来保护从CloudFlare到密钥服务器的连接。以前,我们描述了只在一个方面进行身份验证的TLS握手:客户端验证了服务器。在相互认证的TLS中,客户端和服务器都具有证书并进行身份验证。关键服务器认证CloudFlare,CloudFlare认证密钥服务器。

在无钥匙SSL中,密钥服务器仅允许具有由CloudFlare内部证书颁发机构签名的证书的客户端的连接。我们使用我们自己的证书颁发机构为此连接双方授予的证书。我们对如何授予这些证书进行了严格的控制,并使用X.509扩展密钥使用选项来确保证书只能按预期使用。这样可以防止没有授予CloudFlare证书的任何一方与密钥服务器进行通信。客户还可以选择添加防火墙规则来限制来自CloudFlare的IP空间的传入连接。

此外,我们将此连接的密码套件限制为以下之一:

ECDHE-ECDSA-AES256-GCM-SHA384

ECDHE-RSA-AES256-GCM-SHA384

这些是OpenSSL中最强大的密码之一,可以保证CloudFlare和密钥服务器之间的连接具有完美的前瞻性保密。

其他安全考虑

关键服务器本身可以修改为与硬件安全模块(HSM)一起工作,为希望保护密钥服务器的客户提供额外的硬件安全性,以免与Heartbleed类似的未被发现的软件漏洞。

关键服务器不受Bleichenbacher的填充oracle攻击,因为它使用不变的大小响应。只要在密钥服务器上使用的底层加密库是免疫的,侧信道攻击(如定时攻击)无效。我们在参考实现中使用了OpenSSL,已经针对这种攻击而加以强化。

性能增强

CloudFlare旨在使网站更快:在CloudFlare上连接到与CloudFlare相同的站点所需的时间较短。Keyless SSL也是如此。连接到具有无钥匙SSL的站点应该比禁用CloudFlare的连接更快。人们已经询问如何,因为无钥匙SSL需要与密钥服务器的额外连接。答案在于地理学。

CloudFlare的数据中心在全球20个国家的地理位置分布,占互联网活跃人口95%的不到20ms。这允许访问者与网络上与他们最接近的CloudFlare服务器进行通信。访问者和CloudFlare之间发送的消息不必太远,因此连接延迟较小。这种邻近效应是CloudFlare加速网站的方式之一。

在上述无钥匙SSL图中,除了一个消息之外的所有消息都是通过CloudFlare和访问者之间的短链接进行的。唯一的长途往返是一个关键的服务器。

illustration-ssl-with-cf-and-without.png

考虑旧金山的访客想访问通过TLS托管在伦敦的网站的情况。没有CloudFlare,TLS握手需要从旧金山到伦敦的两次往返。随着无钥匙SSL和托管在伦敦的键盘服务器,访客将最终在CloudFlare附近的圣荷西数据中心。在这种情况下,只有一条消息必须前往伦敦并返回。消息必须行驶较短距离,从而加快握手速度。

我们只需要一次往返密钥服务器的原因是持续连接。一旦CloudFlare连接到一个密钥服务器,它可以使任何新访问者的连接准备好。与无钥匙SSL供电站点的第一个连接速度很快,但是当访问者返回到站点时,主要的性能提升就是这样。

缩短握手

TLS提供了一个非常出色的性能功能,称为“会话恢复”。如果客户端以前已经与服务器建立了会话,并且正在尝试再次连接,则可以使用缩写的握手。有两种机制:会话ID和会话单。

会话ID要求服务器保持会话状态(即会话密钥),以备前一个会话需要恢复。在会话凭证的情况下,服务器在初次握手期间向客户端发送会话凭证(由会话密钥加密的凭证密钥组成)。当恢复会话时,客户端将加密的密钥发送回解密它的服务器并恢复会话。没有必要使用私钥进行会话恢复。

Firefox和Chrome是支持会话门票的主要浏览器。所有其他现代浏览器都支持通过会话ID恢复。在大规模使用这些技术时面临的挑战之一是负载平衡。为了使服务器恢复连接,需要具有先前建立的会话密钥。如果访问者尝试恢复与新服务器的连接,则该服务器需要以某种方式获取原始会话密钥。

会话恢复的主要问题是,这并不意味着扩展到负载平衡的服务器。如果客户端在一台服务器上启动会话,则无法在另一台服务器上恢复该会话。这不是协议的失败,只是开源Web服务器中缺少的功能。

凭借无钥匙SSL,我们引入了高级会话恢复功能来解决这个问题。这包括通过会话凭证和通过会话ID在数据中心内恢复会话的全球会话恢复。会话恢复允许重复的访问者具有快速的闪电连接时间,因为不需要返回密钥服务器来恢复连接。

session_resumption_with_session_ticket.jpg

使用会话券,我们可以从网络上的任何机器恢复会话。这需要我们向社区开放的重要的工程工作。

会话恢复会话门票

Twitter 最近宣布,他们正在使用每12小时轮换的会话票钥。我们正在通过每小时旋转会话票钥匙来提高安全性。我们建立了一个集中的会话票据密钥生成器,每小时发出一次新的密钥,以便在全球网络上进行分发。每个密钥持续存在用户可配置的时间(默认为96小时),之后它将被永久删除。为了分发密钥,我们向键盘存储京都大亨添加了一个TLS层,以便复制完全通过相互验证的TLS进行加密,并固定到CloudFlare的CA。凭借京都大亨,票价钥匙将在数秒内全球复制到我们的每台边缘机器。符合我们的开源哲学,我们计划开放采购我们对京都大亨的变化。通过每个服务器上提供的票证密钥,我们可以在整个网络中的任何机器上恢复任何连接。

机票钥匙的轮换有助于我们为客户保持完美的前卫保密,同时减少返回访问者使用Firefox和Chrome的延迟。

会话ID恢复

我们也可以在具有会话ID的多个机器上恢复会话。与会话券不同,我们只能在数据中心内恢复会话。事实证明,对于99.99%的用户而言,因为CloudFlare的Anycast网络将请求引导到最近的数据中心,这一点已经足够好了。浏览器通常不经常在城市之间移动,所以大多数恢复请求最终在同一个地方。而且,在最坏的情况下,如果您从一个城市的手机访问一个站点,然后飞往另一个城市,您的客户端将简单地设置一个新的会话。

session_resumption_with_session_id.jpg

我们可以通过缓存数据中心内的会话密钥来使用ID来恢复会话。对于每个新的连接,我们将会话密钥的加密版本缓存在由会话ID索引的集中位置。如果一个新的请求来自之前已经看到的会话ID,我们可以在中央存储中查找,可以从任何数据中心的所有服务器访问。这些会话密钥不会离开数据中心并持续存在用户可配置的时间长度,再次默认为96小时。会话ID缓存可让我们在Chrome或Firefox以外的浏览器中使用缩写握手几乎所有恢复的连接尝试。

其他技术复杂的组织也使用会话恢复。例如,Google使用类似的技术在其基础架构上恢复会话。注意: 启用SSL的所有CloudFlare客户现在可以获得此高级会话恢复的好处,即使它们不使用无钥匙SSL。

开源

CloudFlare在构建无钥匙SSL时开发了大量代码,并将其主要部分归功于社区:

严格SSL:此代码允许来自NGINX的上游连接验证TLS连接,用于验证密钥服务器的身份。此更改已合并到NGINX中。

会议门票:我们在NGINX中增加了会话票的支持。此更改已合并到NGINX中。

CFSSL:我们最近开始采用我们用于内部证书颁发机构的工具。它在GitHub上可用。

京都大亨:我们很快开始采购我们对京都大亨的改变,京都大亨是我们广泛使用的高性能键值存储,允许相互验证的复制。

密钥服务器: Keithess SSL密钥服务器的参考实现现在可以在Github上使用。

为什么重要

无钥匙SSL是一个很大的进步,允许网站所有者使用像CloudFlare这样的服务,使他们的网站更快更安全,同时保持对其私钥的控制。正如我们在上一篇文章中所说的,Sebastien能够在一夜之间建立起初始的无钥匙SSL原型。确保它是安全,快速,可以扩大是我们两年的工程。现在,通过持续连接和高级会话恢复技术,使用无钥匙SSL不仅安全,而且速度快!

参考文档1:无钥匙SSL:Nitty Gritty技术细节

参考文档2:宣布无钥匙SSL™:CloudFlare的所有好处,而不必翻转私人SSL密钥

未经允许不得转载:江哥架构师笔记 » keyless ssl原理

分享到:更多 ()

评论 抢沙发

评论前必须登录!