本文深入探讨了Passkey背后的密码学原理,包括WebAuthn规范如何增强安全性以抵抗网络钓鱼,以及Authenticator的类型。同时讨论了Passkey的威胁模型、局限性,以及用于密钥生成和证书存储的扩展功能。最后,文章为用户和开发者提供了采用Passkey的建议,并展望了其在现代身份验证系统中的未来。
当大多数人想到密码学时,他们通常首先想到的是加密:保持信息的机密性。但同样重要(如果不是更重要的话)的是真实性:确保信息确实来自真实的来源。当你访问网站时,服务器通常通过 Web 公钥基础设施 (PKI) 认证的传输层安全 (TLS) 证书来证明其身份。密码是用户身份验证的传统解决方案,但它们容易受到网络钓鱼攻击和数据泄露的影响。这就是 Passkey 出现的原因。
本文不会解释 Passkey 是什么以及为什么它们比密码更好--一些 许多 其他 资源 已经涵盖了这些内容--本文将研究 Passkey 背后的密码学,它们所提供的保证,以及你可以使用它们做的有趣的密码学事情,例如生成加密密钥和存储证书。你需要了解 Passkey 背后的密码学才能正确地实现安全身份验证。我们还将讨论主要的 Passkey 规范 WebAuthn,并向你展示如何使用 Passkey 机制的扩展来构建具有不同功能的更复杂的系统。
Passkey 的核心只是用于生成数字签名的密钥对。注册 Passkey 时,网站会保存公钥和一个标识符。通过 Passkey 验证用户身份时,网站会提供一个 Challenge,并等待包含此 Challenge(以及一些其他元数据,例如标识符)的签名响应。该标识符用于查找公钥,该公钥用于验证签名。
从密码学的角度来看,这非常简单。私钥验证用户身份,但不会将对攻击者有用的敏感信息传递给服务器。如果服务器 Challenge 生成正确--例如,作为 32 字节的均匀随机序列--那么它将防止重放攻击。由于服务器只保存公钥,并且用户不发送敏感信息,因此在发生黑客攻击时不会泄露任何信息。
但仅靠数字签名不足以解决网络钓鱼问题。如果我们就此止步于密码学原语,用户仍然容易受到攻击。例如,如果没有额外的保护措施,攻击者可能会诱骗用户签署错误网站的 Challenge,或者在多个网站上重复使用相同的密钥对。
这就是为什么 Passkey 构建在 W3C 的 WebAuthn 规范之上的原因,该规范在基本密码学之外增加了关键的安全属性。让我们看看 WebAuthn 如何将这些简单的密码学原语转换为防网络钓鱼的身份验证系统。
WebAuthn 是 Passkey 背后的主要规范。简单来说,用户通过他们的 浏览器(WebAuthn 用户代理)在诸如笔记本电脑、手机或 PC(客户端设备)的 设备 上访问 网站(信赖方)。浏览器与 Authenticator 交互,Authenticator 是一种硬件或软件,用于生成 Passkey 密钥对,并使用此密钥对创建数字签名。
图 1:Passkey 身份验证流程的简化视图。
在上图中,你可以看到 Passkey 身份验证的工作原理:
(浏览器和 Authenticator 之间的这种交互在另一个规范中更详细地描述:FIDO 联盟的 客户端到 Authenticator 协议 (CTAP))。这是一个简化的描述;WebAuthn 规范允许更多种类的用例(例如,一切都可以通过移动应用程序而不是网站/浏览器来工作)。但是,这些细节与理解 Passkey 如何与密码学一起工作无关。
WebAuthn 通过源绑定来解决网络钓鱼问题。该规范要求浏览器向 Authenticator 提供请求的 源(即网站域名)。Authenticator 反过来仅在发出请求的网站与创建 Passkey 的网站匹配时才使用 Passkey。
这意味着如果你为 bank.com 创建一个 Passkey,则假冒网站 fake-bank.com 根本无法使用它--你的 Authenticator 将拒绝该请求。每个网站还获得其自己唯一的密钥对,从而完全消除了密码重用问题。
此外,该规范仅允许使用 HTTPS 的源,这意味着该请求来自具有相应源的有效证书的服务器。
通常,Authenticator 是“你拥有的东西”。所有 Authenticator 都可以检查用户在身份验证时是否实际存在。一些 Authenticator 还可以根据“他们知道的东西”,例如 PIN,或“他们是什么”,例如他们的生物识别信息来验证用户。
你会遇到的主要 Authenticator 类型有两种:
如果平台可以进行跨平台通信(例如蓝牙),则其平台 Authenticator 也可以通过与另一个设备(例如智能手机1)通信来用作漫游 Authenticator。为了在高价值应用程序中实现最大安全性,我们建议使用专用硬件安全密钥作为你的 Authenticator。
一些 Authenticator 向用户显示它正在为其生成数字签名的请求的详细信息。对于无法执行此操作的 Authenticator,浏览器将改为显示这些详细信息。在批准身份验证请求之前,请务必验证这些详细信息。
当用户在网站上注册 Passkey 时,Authenticator 会生成一个 Passkey 和一个标识符(凭据 ID)。网站存储公钥和标识符,并将它们与用户帐户关联起来。然后,网站可以使用此标识符来告诉 Authenticator 他们想要访问哪个 Passkey。一些 Authenticator 具有大量存储空间,并且它们自己存储所有用户 Passkey。其他 Authenticator 则没有,因此它们会加密 Passkey,并将加密后的 Passkey 作为注册期间的标识符提供给网站。当网站想要验证用户身份时,它会将标识符提供给浏览器,浏览器反过来将其提供给 Authenticator,Authenticator 会对其进行解密并使用 Passkey。本质上,网站正在存储 Passkey,但由于它是加密的,因此如果网站遭到黑客攻击,它的价值有限。
从理论上讲,你可以只将加密密钥对存储在文件中,编写一些围绕它的软件,使用此密钥对进行加密操作,并假装它是一个 Authenticator。但是,网站如何知道其用户是否正在使用安全的 Authenticator?Authenticator 可以通过在用户创建 Passkey 时生成证明声明来以加密方式证明有关其来源的某些事实,例如谁制造了它;该声明由制造商签名的证书链支持。这对于企业用户尤其有用,因为它允许企业确保所有用户都具有满足某些安全要求的特定 Authenticator。但是,证明是可选的:WebAuthn 规范不要求 Authenticator 支持它。
最后,与任何“你拥有的东西”的身份验证因素一样,一个重要的问题是,当你丢失它或它坏了会发生什么?一般来说,丢失 Authenticator 意味着丢失由它控制的所有 Passkey。由于 Passkey 本质上是随机生成的加密密钥对,因此实际上没有恢复的希望。大多数平台 Authenticator,例如 iCloud 钥匙串,Google 密码管理器和 1Password,允许通过将 Passkey 同步到云来进行备份。但是,这始终是一种权衡:可恢复的 Passkey 具有更大的攻击面,因为攻击者可能会尝试通过恢复机制来获取 Passkey。通常,重要的是网站要具有恢复机制,以防用户失去对其 Passkey 的访问权限,同时要记住攻击者可能会将此恢复机制作为目标。
虽然使用具有备份功能的平台 Authenticator 降低了丢失 Passkey 的风险,但它并没有消除这种风险。被平台禁止的用户将失去对其 Passkey 的访问权限,并且平台可能会意外删除 Passkey。此外,平台还可以支持 Passkey 共享或家庭帐户,其中多个用户可以访问相同的 Passkey。网站应根据 Passkey 提供的访问权限警告用户这些风险。
尽管你可能听说过一些营销宣传,但 Passkey 并非安全灵丹妙药。让我们看看它们实际上可以防止什么。
Passkey 的威胁模型 显示它们可以防止密码通常可以防止的威胁,同时还可以消除网络钓鱼和密码重用的风险。这是一个显着的改进!WebAuthn 规范的 一致性部分 发表了一个非常强烈的声明,暗示符合该规范的网站,浏览器和 Authenticator 对恶意行为是“安全”的。
这种说法过于简化了安全现实。以下是仍然可能发生的真实攻击场景:
Passkey 不能完全防止大多数用户设备受到威胁,例如恶意浏览器或恶意软件。但是,它们确实可以有效地限制攻击速度,因为每个签名都需要用户与 Authenticator 进行单独的交互。此外,Passkey 不能防止可以通过直接接管或通过子域名劫持来控制网站域名的攻击者。
网站需要考虑的另一件事是凭据 ID 冲突。该规范仅要求它们是 概率上唯一的--这意味着它们是随机生成的,重复的可能性极低(但非零),类似于 UUID。
为什么这很重要?当用户注册 Passkey 时,网站会将凭据 ID 存储为该用户 Passkey 的标识符。如果攻击者可以以某种方式使用与其目标受害者相同的凭据 ID 注册 Passkey,则他们可能会造成身份验证混乱。
这似乎不太可能,但请考虑以下情况:
修复方法很简单:当新 Passkey 的凭据 ID 与数据库中已有的 ID 匹配时,网站应始终 拒绝注册尝试。这创建了一个简单的“先到先得”的保护,以防止凭据 ID 冲突。
WebAuthn 还支持为用于生成凭据和执行身份验证的机制定义扩展。基本上,网站可以通过 WebAuthn API 请求使用一个或多个扩展。浏览器和 Authenticator 将处理这些扩展(如果它们支持),而忽略不支持的扩展。
WebAuthn 规范列出了一些定义的扩展,并链接到互联网号码分配机构 (IANA) 注册表以查找更多扩展的定义。这些扩展的范围从启用与旧 API 的向后兼容性到支持完全不同的加密功能。由于这篇博文是关于密码学的,因此后者的扩展是最有趣的。
其中一个扩展是 WebAuthn 规范称之为 prf
(对于伪随机函数族)的扩展,它构建在 FIDO CTAP v2.1 规范中定义的 hmac-secret
扩展之上。通过 prf
扩展,Authenticator 可以使用固定随机生成的 32 字节 HMAC 密钥计算 HMAC-SHA-256。HMAC 计算的输入是固定 WebAuthn 前缀的 SHA-256 摘要,后跟网站提供的输入。虽然此扩展不够灵活,无法实现像 HKDF 这样的东西,但可以使用它来实现 HKDF Extract2。
另一个这样的扩展称为 largeBlob
,提示支持的 Authenticator 存储一个“大 blob”的不透明数据,网站可以在身份验证断言期间读取或写入该数据。网站可以使用它来存储任何(敏感)数据,例如 证书或加密密钥。
因此,使用这些扩展,可以派生或存储静态加密密钥。正如 largeBlob
示例中建议的那样,你甚至可以将此用于端到端加密。但是,与浏览器设置中密码学的所有应用程序一样,要实现真正的端到端安全性非常困难(如果不是不可能的话)。通常,这要求系统能够抵抗恶意服务器。Web 密码学在由服务器提供的 JavaScript 上运行,这意味着恶意服务器可以只提供恶意 JavaScript,该 JavaScript 提取密钥,将解密的消息发送回服务器等等。更糟糕的是,恶意服务器可以以高度针对性的方式执行此操作,为大多数用户提供正确的 JavaScript,但为特定目标用户提供恶意 JavaScript。为 Web 上的代码实施 子资源完整性(例如,与受信任的第三方存储所有已发布版本的哈希)和 二进制透明度 技术(例如,公开可验证,防篡改的日志)是解决此类问题的两种有前途的解决方案。
此外,重要的是要注意,该规范认为所有扩展都是可选的,这意味着不能保证浏览器和 Authenticator 支持它们。网站在需要特定扩展时需要检查扩展是否可用,否则用户将无法访问其服务。将来,所有主要的浏览器和 Authenticator 都有望支持它们,这可以改善 Web 上密码学的密钥管理。
通常,该规范正在积极开发中,并且还有许多更有趣的扩展空间。可能的扩展包括其他加密原语(例如更高级的签名方案和零知识证明),但单调计数器将是一个有趣的扩展。虽然这并非直接的加密功能,但单调计数器可用于保护外部存储(例如 端到端加密的云存储)免受回滚攻击。
现在是采用 Passkey 的时候了。Passkey 的密码学基础提供了强大的安全保证,使其成为现代身份验证系统在正确实施 WebAuthn 时的明确默认选择。虽然不是一个完善的安全解决方案,但 Passkey 消除了许多几十年来一直困扰密码的关键漏洞:Passkey 永远不会将敏感信息传输到服务器,不能在站点之间重复使用,并且可以通过源绑定来抵抗网络钓鱼。
以下是我们对用户和开发人员的建议:
用户应采用 Passkey,开发人员应尽可能支持它们。硬件安全密钥可为高价值应用程序提供最强的保护,而平台 Authenticator 通常提供更好的用户体验和备份功能。在不受信任的设备上进行身份验证时,请使用来自具有自己显示器的单独设备的 Passkey 来验证身份验证请求。
开发人员应实施帐户恢复机制,因为 Passkey 是无法在丢失时重建的加密密钥对。即使是具有备份功能的平台 Authenticator 也存在用户应理解的风险。
Passkey 可以充当第一个身份验证因素,第二个身份验证因素,甚至 多个身份验证因素。但是,开发人员需要在其更广泛的 威胁模型 中考虑 Passkey。为了防止恶意服务器(例如在 E2EE 应用程序中),请实施子资源完整性和二进制透明度技术。随着 WebAuthn 的发展,新的扩展将启用更多的加密应用程序,尽管不同浏览器和 Authenticator 的支持各不相同。
如果你正在实施 Passkey 或探索 WebAuthn 扩展的新颖用途,请 与我们联系 以评估你的设计和实施,并帮助保护你的用户。
智能手机通常还支持一种称为“混合传输”的东西,在该传输中,手机通过 WebSockets 与浏览器通信,同时通过蓝牙低功耗单独证明其与浏览器的物理接近度。↩︎
HKDF Extract 的盐参数将是凭据的随机生成的 32 字节密钥,输入密钥材料将是 SHA-256 摘要。结果值可用作 HKDF Expand 的伪随机密钥。不建议以这种方式为每个 Passkey 生成多个伪随机密钥。相反,可以通过改变 HKDF Expand 的 info 参数来从单个伪随机密钥派生多个密钥。↩︎
- 原文链接: blog.trailofbits.com/202...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!