深入解析Passkeys:WebAuthn技术的未来与实现

本文详细介绍了WebAuthn技术中的Passkeys实现机制,涵盖认证器工作原理、RP ID规范、用户标识管理以及多设备同步策略,为开发者提供完整的技术架构解析和实践指南。

ImperialViolet - Passkeys

ImperialViolet

Passkeys (2022年7月4日)

演示文稿现已发布(Google I/O、WWDC):我们正在推动WebAuthn技术的大规模普及。

WebAuthn在企业用户和技术娴熟用户中已经运行得相当不错。但是,当使用模式要求用户必须购买一对安全密钥、确保在每个网站注册备份密钥,同时还要将其存放在防火保险箱中时,我们无法实现广泛采用。因此,面向消费者的模式用手机取代安全密钥,并用备份私钥本身来替代拥有备份认证器的需求。这本来可以是一个不同的API,但为公钥认证提供第二个Web API会带来很大负担,所以仍然选择WebAuthn。基于WebAuthn也意味着您仍然可以使用安全密钥*,并且希望支持更多网站范围。

(*尽管今年在Android上还不行,因为它尚未支持足够新版本的CTAP。抱歉。)

WebAuthn规范并非温和的入门指南,但您可以找到多个关于如何进行API调用的指南。可能还会有更多指南出现。本文想要涵盖的是关于passkeys的基础语义。如果您完全熟悉WebAuthn,这些内容并不新鲜,但如果您仅在双因素认证场景中使用过WebAuthn,那么这些是新的内容。

我可能会在未来的文章中在此基础上展开,也许会将过去的一些文章合并成一份文档。下一段直接深入内容,没有太多背景介绍。也许对某些人有用,但最好将其理解为我正在积累的更完整文档的片段。

好的:

认证器是从(RP ID,用户ID)对到公钥凭证的映射。我将扩展每个术语:

传统上,认证器是持有密钥并进行签名的物理设备。安全密钥就是认证器。笔记本电脑也可以;Windows Hello已经作为认证器有一段时间了。在passkeys的世界中,手机是重要的认证器。现在密钥可以同步,您可能会将同步账户本身视为分布式认证器。因此,不要将认证器视为物理设备,而是将其视为维护包含用户凭证的映射的任何东西。

RP ID标识一个网站。它是一个包含域名的字符串。(在非Web情况下,如SSH,它可以是URL,但这里不涵盖这些情况。)网站可以使用RP ID,如果该RP ID等于或后缀于网站的域名,并且RP ID至少是eTLD + 1。因此,https://foo.bar.example.com 可以使用RP ID:foo.bar.example.com、bar.example.com和example.com,但不能使用com(因为那少于eTLD + 1),也不能使用example.org(因为那是无关的域名)。由于凭证映射由RP ID键控,一个网站无法使用另一个网站的凭证。但是,请注意子域名:usercontent.example.com可以使用example.com作为RP ID,尽管客户端数据会让服务器知道哪个源发出了任何给定请求。

接下来,用户ID是一个不透明的字节字符串,用于标识网站上的账户。规范说它不能包含可识别信息(即不要直接使用用户的电子邮件地址),因为安全密钥对用户ID的保护程度不如对其他信息的保护。建议是在用户表中添加一列,根据需要生成一个大的随机值,并为每个用户存储在那里。(规范说64字节,但如果您从安全随机源生成16字节,我认为也可以。)您也可以对内部用户ID进行HMAC,尽管那会将风险集中在那个HMAC密钥上。

回想一下,认证器将(RP ID,用户ID)对映射到凭证?重要的后果是,如果网站创建了一个凭证,它将覆盖具有相同用户ID的任何现有凭证。因此,认证器只包含给定账户的单个凭证。(对于已经了解WebAuthn的人:我假设始终使用可发现凭证。)

凭证是各种字段的集合。最明显的是私钥,但也有元数据:例如RP ID和用户信息。用户信息有三部分:用户名、显示名和ID。我们已经介绍了用户ID。另外两个是自由格式的字符串,在UI中显示以帮助用户选择凭证。用户名通常是用户向网站标识自己的方式,例如电子邮件地址。显示名是用户希望被称呼的方式,可能是他们的法定名称。两者中,用户名在UI中可能更突出。

最后,passkey是一个WebAuthn凭证,在用户需要时是安全且可用的,即已备份。并非所有实现都会立即备份凭证,这些平台上的passkeys可以称为“单设备passkeys”,这有点尴尬,但缺乏备份也是如此。

结构中的另一个重要方面是,虽然一个账户只有一个密码,但它可以有多个passkeys。这是因为passkeys不能像密码那样被复制粘贴。相反,用户将根据需要注册passkeys以覆盖他们的设备集。

断言结构中的authenticatorAttachment字段向网站提示何时可能需要额外的passkey。如果该字段的值是跨平台的,那么用户必须使用另一台设备登录,可能值得询问他们是否要注册本地设备。

当网站上注册了多个passkeys时,用户需要管理它们。网站通常通过用户账户设置中的显式列表来管理双因素WebAuthn凭证。通常,用户在注册时会被提示命名凭证以区分它们。如果您喜欢,这仍然是管理passkeys的合理方式。(我们考虑过浏览器是否可以在注册时发送passkey“名称”以避免提示用户输入,但在同步的世界中,似乎没有既不过于通用(例如“Google设备”)又不涉及隐私问题(例如同步账户标识符)的好值。)

如果提示输入名称并拥有显式列表看起来太复杂,那么我认为也可以简单地有一个重置按钮,该按钮a)注册一个新的passkey,b)删除账户上的所有其他passkey,c)注销所有其他会话。即,一个镜像密码重置流程的按钮。对于许多网站来说,这会很好用。

我们不希望密码作为被忽视的薄弱环节永远留在账户上。为了指导网站确定何时值得提示用户删除密码,认证数据中有一个新的备份状态位,服务器在每次认证时都会收到。如果设置了该位,则passkey将在设备丢失后存活。(除非设备在创建passkey后但在成功同步之前被销毁。但这与在密码管理器中生成随机密码相同。)

关于使用该位没有严格的规定,但一旦用户在便携式认证器上有了备份的passkey,那么可能就是时候询问是否删除密码了。当网站看到创建或断言操作设置了备份状态位,并且附件是跨平台的,或者是平台的但该平台是移动设备时,网站可以知道这一点。这是一组保守的规则,因为例如,在MacBook上创建的凭证可能会同步到用户的iPhone。但也许该用户没有iPhone。

如您所见,passkeys的挑战之一是复杂性!Google的几个团队仍在努力完善在I/O上演示的内容,但我们知道良好的指导将很重要。与此同时,我很乐意在Twitter上回答问题,并考虑公开办公时间是否也会有帮助。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计