不透明:永远不会离开设备的密码

2021-01-02 08:16:52

密码是个问题。由于大多数读者所熟悉的原因,它们是一个问题。对于我们Cloudflare而言,问题更加深远和广泛。大多数读者会立即意识到,难以记住和管理密码,尤其是随着密码要求变得越来越复杂。幸运的是,有很棒的软件包和浏览器附加组件可帮助您管理密码。不幸的是,更大的潜在问题超出了软件解决的范围。

基本的密码问题很容易解释,但很难解决:保证离开您的密码的安全性,无论它的复杂性或猜测的难度有多大,都可以保证。密码因其本身而不安全。

您可能会说:“但是密码始终以加密格式存储!”那很好啊。更准确地说,它们很可能存储为盐腌哈希,如下所述。更糟糕的是,无法验证密码的存储方式,因此我们可以假设在某些服务器上密码以明文形式存储。事实是,即使(负责任地)付出了巨大的努力,即使负责任地存储的密码也可能被泄露和破坏。日益迫切的问题源于密码本身的性质:如今,任何直接使用密码的行为都意味着必须以明文形式处理密码。

您说:“但是我的密码是通过HTTPS安全传输的!”这是真的。

您说,“但是我知道服务器以安全的哈希表形式存储我的密码,因此没有人可以访问它!”好吧,这使人们对服务器充满信心。即便如此,我们只能说是,这也可能是对的。

但是,还有一个重要的警告-端到端使用密码方面的差距。考虑一下,一旦服务器接收到密码(介于安全传输和安全存储之间),就必须读取并处理该密码。是的,作为明文!

而且情况变得更糟–由于有太多人习惯于使用软件进行思考,因此很容易忘记硬件的漏洞。这意味着即使软件受到某种程度的信任,密码也必须在某个时候驻留在内存中。密码必须在某个时刻通过共享总线传输到CPU。这些以多种形式向旁观者提供了攻击的载体。当然,这些攻击媒介的可能性远小于传输和永久存储所呈现的那些,但它们的危害程度也同样如此(最近的CPU漏洞,如Spectre和Meltdown应当作为一个明显的提醒)。

解决此问题的唯一方法是完全删除密码。还有希望!研究和私营部门社区正为此而努力。新标准正在涌现并日趋成熟。不幸的是,密码无处不在,以至于要花很多时间才能同意并用新的标准和技术取代密码。

在Cloudflare,我们一直在询问是否有可以立即完成的工作。今天深入探讨OPAQUE是一个可能的答案。 OPAQUE是众多系统示例中的一种,它使密码在不离开您的财产的情况下就变得有用。没有人喜欢密码,但是只要使用了密码,至少我们可以确保永远不会丢失密码。

我将第一个承认基于密码的身份验证令人讨厌。密码难以记住,输入乏味且非常不安全。减少或替换密码的举措很有希望。例如,WebAuthn是主要用于使用硬件(或软件)令牌的公钥密码术的Web身份验证的标准。即便如此,密码还是作为身份验证机制而令人沮丧的持久性。无论他们的持久性是由于其易于实施,对用户的熟悉还是在网络上和其他地方的普遍存在,我们都希望在他们持久存在的同时,尽可能确保基于密码的身份验证的安全性。

我在Cloudflare的实习重点是OPAQUE,这是一种加密协议,可以解决基于Web的基于密码的身份验证中最明显的安全问题之一:尽管密码通常在传输过程中受到HTTPS的保护,但服务器会以纯文本格式对其进行处理以检查其正确性。处理纯文本密码很危险,因为不小心记录或缓存它们可能会导致灾难性的破坏。该项目的目标不是证明主张采用任何特定协议,而是表明OPAQUE是许多认证中的可行选择。因为网络案例是我最熟悉的,并且可能有很多读者,所以我将以网络为主要示例。

当您在网络上输入密码时,会发生什么?网站必须检查您输入的密码是否与您最初在网站上注册的密码相同。但是该检查如何工作?

通常,您的用户名和密码会发送到服务器。然后,服务器检查与您的用户名关联的注册密码是否​​与您提供的密码匹配。当然,为了防止窃听您的Internet流量的攻击者窃取您的密码,您与服务器的连接应通过HTTPS(TLS上的HTTP)进行加密。

尽管使用了HTTPS,但在此流程中仍然存在一个明显的问题:服务器必须将您的密码表示存储在某个地方。服务器很难保护,而且违反行为也很常见。泄漏此表示可能会导致灾难性的安全问题。 (有关最新违规记录,请访问https://haveibeenpwned.com/)。

为了减少这些泄漏的破坏性,服务器通常将哈希函数应用于用户密码。哈希函数将每个密码映射到一个唯一的,看起来随机的值。将哈希值应用到密码很容易,但是几乎不可能撤消该功能并检索密码。 (也就是说,任何人都可以猜出密码,应用哈希函数并检查结果是否相同。)

使用密码散列,纯文本密码不再存储在服务器上。窃取密码数据库的攻击者不再可以直接访问密码。相反,攻击者必须将哈希应用于许多可能的密码,并将结果与​​泄漏的哈希进行比较。

不幸的是,如果服务器仅对密码进行哈希处理,则攻击者可以下载包含数万亿个可能的哈希值的哈希表,并且几乎可以立即检索纯文本密码。 (有关一些彩虹表的列表,请参见https://project-rainbowcrack.com/table.htm)。

考虑到这一点,一个很好的纵深防御策略是使用加盐哈希,即服务器将您的密码散列到每个用户的随机随机值salt中。服务器还将盐与用户名一起保存,因此用户永远不会看到或不需要提交它。当用户提交密码时,服务器将使用salt重新计算此哈希函数。然后,窃取密码数据(即密码表示形式和盐值)的攻击者必须一个一个地猜出通用密码,并将(加盐的)哈希函数应用于每个猜出的密码。现有的彩虹表没有帮助,因为它们没有考虑到盐分,因此攻击者需要为每个用户创建一个新的彩虹表!

(希望)这样可以充分降低攻击速度,使服务可以通知用户安全漏洞,以便他们可以更改密码。此外,应通过多次应用哈希来进一步加慢攻击速度,以强化盐渍的哈希值。 (有关更详细的讨论,请参见https://blog.cloudflare.com/keeping-passwords-safe-by-staying-up-to-date/)。

这两种缓解策略是在传输过程中对密码进行加密,以及存储腌制,硬化的哈希值,这是当前的最佳做法。

仍然有一个较大的安全孔。基于TLS的密码(我们将其称为)要求用户在登录期间向服务器发送纯文本密码,因为服务器必须看到这些密码才能与文件中已注册的密码匹配。甚至是信誉良好的服务器也可能会意外缓存或记录您的密码尝试,或者在检查密码的过程中损坏。 (例如,Facebook在2019年检测到它不小心存储了数亿纯文本用户密码)。理想情况下,服务器根本不应该看到纯文本密码。

但这是一个很大的难题:如果您从未看到密码,如何检查密码?输入OPAQUE:密码认证密钥交换(PAKE)协议,该协议同时证明密码知识并导出秘密密钥。在详细描述OPAQUE之前,我们首先将概述一下PAKE的功能。

密码验证密钥交换(PAKE)由Bellovin和Merrit [1]在1992年提出,其最初的动机是允许密码验证,而不会基于通过不安全通道传输的数据进行字典攻击。

本质上,简单或对称的PAKE是一种加密协议,它允许仅共享密码的两个方建立强共享密钥。 PAKE的目标是:

2)参与者无需信任第三方(尤其是无需公钥基础设施),

3)不参与协议的任何人(包括知道密码的人)都不会学习到生成的密钥。

4)该协议不会透露彼此的密码(除非密码匹配),也不会透露给窃听者。

总之,成功攻击协议的唯一方法是在参与协议时正确猜测密码。 (幸运的是,此类攻击通常可以通过限制速率来阻止,即在一定数量的错误密码尝试后阻止用户登录)。

它依赖于WebPKI,WebPKI信任称为证书颁发机构的第三方(请参阅https://blog.cloudflare.com/introducing-certificate-transparency-and-nimbus/,以获取有关WebPKI及其某些缺点的深入说明)。

TLS上的密码无法为用户提供任何保证,让其知道服务器是否知道其密码或密码的派生产品-服务器可以接受用户的任何输入而无需任何检查。

就是说,简单的PAKE仍然比TLS上的密码差,只是因为它要求服务器存储明文密码。如果我们想击败当前的做法,我们需要一个PAKE来让服务器存储盐腌的哈希。

相对于普通PAKE的改进就是所谓的非对称PAKE(aPAKE),因为只有客户端知道密码,而服务器才知道哈希密码。一个aPAKE具有PAKE的四个属性,以及另外一个:

5)窃取服务器上存储的密码数据的攻击者必须执行字典攻击才能检索密码。

但是,大多数现有的aPAKE协议存在的问题是,它们不允许加盐散列(否则,它们要求将盐传输给用户,这意味着攻击者可以事先访问盐并可以开始在窃取任何数据之前为用户计算彩虹表)。因此,我们希望按以下方式升级安全性属性:

5 *)窃取服务器上存储的密码数据的攻击者必须对每个用户进行字典攻击,以在数据遭到破坏后检索密码。

OPAQUE是第一个具有正式安全证明的aPAKE协议,该协议具有此属性:它允许完全保密的盐。

OPAQUE是一种强大的aPAKE,它简单地意味着它通过在服务器上使用秘密加盐的哈希来抵御这些预先计算的攻击。 OPAQUE由Stanislaw Jarecki,Hugo Krawcyzk和Xujiayu于2018年提出并进行了正式分析(全部披露:Stanislaw Jarecki是我的学术顾问)。名称OPAQUE是两个密码协议名称的组合:OPRF和PAKE。我们已经知道PAKE,但是什么是OPRF? OPRF代表“遗忘伪随机函数”,这是一种协议,通过该协议,双方可以计算确定性的函数F(key,x),但输出看似随机的值。一方输入值x,另一方输入键-输入x的一方学习结果F(key,x),但不学习键,提供键的一方学不到任何东西。 (您可以在此处深入了解OPRF的数学方法:https://blog.cloudflare.com/privacy-pass-the-math/)。

OPAQUE的核心是一种将用户机密存储在服务器上的安全方法,而无需授予服务器访问这些机密的权限。服务器没有存储传统的加盐密码哈希,而是为您存储了一个秘密信封,该信封被两个信息“锁定”:只有您自己知道的密码和只有服务器才知道的随机秘密密钥(如盐) 。要登录,客户端将启动一个加密交换,该交换将信封密钥显示给客户端,但重要的是,不会显示给服务器。

然后,服务器将信封发送给用户,该用户现在可以检索加密的密钥。 (信封中包含的密钥是用于用户的私钥-公共密钥对,以及用于服务器的公共密钥。)这些密钥一旦解锁,将成为Authenticated Key Exchange(AKE)协议的输入,该协议允许用户和服务器建立一个秘密密钥,该密钥可用于加密他们未来的通信。

在注册之前,用户首先注册服务并选择用户名和密码。注册从我们刚刚描述的OPRF流程开始:Alice(用户)和Bob(服务器)进行OPRF交换。结果是Alice具有一个随机密钥rwd,该随机密钥是从OPRF输出F(key,pwd)导出的,其中key是特定于Alice的服务器拥有的OPRF密钥,而pwd是Alice的密码。

在他的OPRF消息中,鲍勃发送其OPAQUE身份的公共密钥。然后,爱丽丝会生成一个新的私钥/公钥对,这将是她对鲍勃服务的永久OPAQUE身份,并使用rwd加密她的私钥以及鲍勃的公钥(我们将结果称为加密信封)。她将这个加密的信封连同她的公共密钥(未加密)一起发送给Bob,后者将她提供的数据以及Alice的特定OPRF密钥秘密存储在由她的用户名索引的数据库中。

登录阶段非常相似。它以与注册相同的方式开始-带有OPRF流程。但是,在服务器端,鲍勃没有生成新的OPRF密钥,而是查找了他在爱丽丝注册期间创建的密钥。为此,他查找了爱丽丝的用户名(她在第一条消息中提供的用户名),并检索了他的记录。该记录包含她的公钥,她的加密信封以及鲍勃(Bob)对爱丽丝(Alice)的OPRF密钥。

他还发送了加密的信封,爱丽丝可以使用OPRF流的输出对其进行解密。 (如果解密失败,她将中止该协议-这很可能表明她输入了错误的密码,或者Bob不是他说的那样)。如果解密成功,她现在将拥有自己的秘密密钥和鲍勃的公共密钥。她与Bob一起将它们输入到AKE协议中,Bob依次输入了他的私钥和她的公钥,这给了他们两个新的共享密钥。

这里要问的一个重要问题是:哪种AKE适合不透明?新兴的CFRG规范概述了几种选择,包括3DH和SIGMA-I。但是,在网络上,我们已经可以使用AKE:TLS!

回想一下,TLS是一个AKE,因为它提供了具有共享秘密派生的单边(和相互)身份验证。 TLS的核心是Diffie-Hellman密钥交换,该密钥交换本身未经身份验证,这意味着运行它的各方无法验证与谁一起运行。 (这是一个问题,因为当您登录银行或存储您的私人数据的任何其他网站时,您需要确保他们是他们所说的人)。身份验证主要使用证书,这些证书由受信实体通过称为公钥基础结构(PKI)的系统颁发。每个证书都与一个密钥相关联。为了证明其身份,服务器将其证书提供给客户端,并使用其私钥对TLS握手进行签名。

在网络上修改这种无处不在的基于证书的身份验证可能不是最佳的起点。相反,一种改进将是在TLS握手完成之后使用OPAQUE对TLS共享机密进行身份验证。换句话说,一旦使用其典型的WebPKI证书对服务器进行身份验证,客户端便可以随后对该服务器进行身份验证。可以使用OPAQUE在TLS连接中进行“后握手”身份验证。

导出的身份验证器是TLS中“握手后”身份验证的一种机制。它们允许服务器或客户端提供身份证明,而无需设置新的TLS连接。回想一下,在标准的Web案例中,服务器使用证书来建立其身份(例如,证明它们是“ cloudflare.com”)。但是,如果同一服务器还拥有备用身份,则它们必须再次运行TLS以证明自己是谁。

导出的身份验证器基本流程的工作类似于经典的质询-响应协议,其工作方式如下。 (我们将仅考虑服务器身份验证的情况,因为客户端的情况是对称的)。

建立TLS连接后的任何时候,Alice(客户端)都会发送身份验证器请求,以表明她希望Bob(服务器)证明其他身份。该请求包括上下文(不可预测的字符串-将此视为挑战),以及扩展,包括有关要提供客户端身份的信息。例如,客户端可以包括SNI扩展名,以向服务器请求与某个域名相关联的证书,而不是最初用于TLS连接的域名。

在接收到客户端消息后,如果服务器具有与该请求相对应的有效证书,则它将发回一个导出的身份验证器,以证明它具有该证书的密钥。 (此消息与TLS 1.3握手中来自客户端的Auth消息具有相同的格式-它包含一个证书,一个CertificateVerify和一个Finished消息)。如果服务器不能或不希望通过请求的证书进行身份验证,它将以空身份验证器答复,该身份验证器仅包含格式正确的“完成”消息。

然后,客户端检查其收到的导出的身份验证器格式正确,然后验证所提供的证书是否有效,如果是,则接受新的身份。

总之,通过使用经过严格审查的TLS加密和消息格式,导出的身份验证器可以在更高的层(例如应用程序层)中安全地提供身份验证。此外,它与TLS会话相关联,因此无法将身份验证消息从一个TLS连接复制并粘贴到另一个TLS连接中。换句话说,导出的身份验证器提供了将基于OPAQUE的身份验证添加到TLS所需的正确钩子。

OPAQUE-EA允许OPAQUE在已建立TLS连接之后的任何时间运行。回想一下Bob(服务器)将存储他的OPAQUE身份(在这种情况下为签名密钥和验证密钥),而Alice将其身份(已加密)存储在Bob的服务器上。 (Alice存储她的加密密钥的注册流程与常规OPAQUE中的相同,只是她存储了签名密钥,因此我们将直接跳至登录流程)。爱丽丝(Alice)和鲍勃(Bob)运行两个请求身份验证的EA流,每一方一个,并且OPAQUE协议消息随即出现在EA的扩展部分中。让我们详细看看它是如何工作的。

首先,爱丽丝根据她的密码生成她的OPRF消息。她创建了一个身份验证器请求,询问鲍勃的OPAQUE身份,并在扩展名字段中包含了她的用户名和OPRF消息,并将其通过已建立的TLS连接发送给鲍勃。

鲍勃收到消息并在他的数据库中查找爱丽丝的用户名。他检索了包含验证密钥和加密信封以及OPRF密钥的OPAQUE记录。他在OPRF消息上使用OPRF密钥,并创建一个Exported Authenticator,以证明其OPAQUE签名密钥的机密。

......