Language:Chinese VersionEnglish Version

编者按:密码已经奄奄�息十年了,但2026年才是真正可行的替代方案出现的一年。Michael Sun将深入探讨passkeys和WebAuthn的实际应用情况——哪些已经可以投入生产,哪些还不够完善,以及如何在无密码认证的同时避免将用户拒之门外。

密码从来就是个坏主意

密码模式要求人类做一些他们根本不擅长的事情:生成、记忆和管理数百个独特的高熵字符串。自1960年代以来我们就知道这一点。整个密码管理器行业都是为了修补这个有缺陷的模型而存在的。

但几十年来,密码之所以持续存在,是因为替代方案更糟糕。硬件令牌价格昂贵且容易丢失。生物识别系统不可靠且是专有的。基于短信的双因素认证增加了摩擦,并且容易受到SIM卡交换攻击。每个”密码杀手”最终都变成了密码的补充——在密码之上增加另一层,而不是取代它们。

WebAuthn和passkeys改变了这一局面。我们第一次有了无密码认证标准,它得到所有主流浏览器的支持,所有主流平台供应商的支持,并且实际上比输入密码对用户来说更简单。技术已经成熟。现在的问题是实施。

理解技术栈

WebAuthn:基础

WebAuthn(Web认证API)是W3C标准,使浏览器能够实现无密码认证。它定义了一个协议,其中浏览器在Web应用程序(”依赖方”)和认证器(能够生成和验证加密凭据的设备)之间进行调解。

流程很简单。在注册期间,认证器生成一个公钥-私钥对。公钥被发送到服务器。在认证期间,服务器发送一个挑战,认证器用私钥对其进行签名,服务器用存储的公钥验证签名。永远不会创建、传输或存储密码。

WebAuthn自2019年以来一直是标准,但最初采用缓慢,因为认证器指的是物理安全密钥——YubiKeys、Titan密钥。用户必须购买硬件、随身携带,并处理”如果我丢了怎么办”的问题。Passkeys解决了这个问题。

Passkeys:适用于所有人的WebAuthn

Passkeys是WebAuthn凭据的用户友好型实现。与将私钥存储在物理安全密钥上不同,passkeys将其存储在平台的凭据管理器中——Apple设备上的iCloud Keychain、Android和Chrome上的Google密码管理器、Windows上的Windows Hello。

关键功能是跨设备同步。当你在 iPhone 上创建密码密钥(passkey)时,它会同步到你的 Mac、iPad 以及任何登录了同一 iCloud 账户的其他 Apple 设备。Google 在 Android 设备和 Chrome 浏览器上也实现了同样的功能。这解决了困扰硬件安全密钥的恢复问题——当你丢失设备时不会失去访问权限。

从用户的角度来看,创建密码密钥的过程如下:网站提示注册,操作系统显示生物识别提示(Face ID、指纹、Windows Hello PIN),然后密码密钥就创建完成了。登录过程也是一样:生物识别提示,完成。无需输入密码,也无需从身份验证应用中复制代码。

FIDO2:协议层

FIDO2 是 WebAuthn(浏览器 API)和 CTAP2(客户端到身份验证器协议)组合的统称。CTAP2 定义了浏览器如何与外部身份验证器通信,包括硬件安全密钥和平台身份验证器。你通常不需要直接与 CTAP2 交互——浏览器会处理它——但了解它的存在有助于你在文档中遇到这个术语时理解它。

在生产环境中实现密码密钥

服务器端设置

你的服务器需要实现 WebAuthn 依赖方(relying party)协议。这意味着生成注册和身份验证挑战,验证身份验证器响应,以及存储凭据数据。已有几个成熟的库:

  • SimpleWebAuthn (TypeScript/JavaScript) — Node.js 应用最受欢迎的选择。文档完善,积极维护,处理加密验证。
  • py_webauthn (Python) — Django 和 Flask 应用的可靠库。
  • webauthn-rs (Rust) — 如果你使用 Rust 构建,这是参考实现。
  • java-webauthn-server (Java) — Yubico 为 JVM 应用提供的库。

关键的服务器端决策是:

  1. 凭据存储: 你需要存储凭据 ID、公钥、签名计数和关联的用户信息。这是一个数据库表,而不是会话存储。像对待密码哈希一样对待它——这是关键的安全数据。
  2. 挑战管理: 注册和身份验证挑战必须是单次使用且有时限的。将它们存储在会话或短期缓存中,TTL(生存时间)为 60-120 秒。
  3. 来源验证: 依赖方 ID 必须与你的域名匹配。这是开发中常见的错误来源——localhost 和生产环境有不同的来源。

前端集成

浏览器提供了 navigator.credentials.create()navigator.credentials.get() API。您的前端代码使用服务器提供的选项调用这些 API,接收身份验证器响应,并将其发送回服务器进行验证。

最大的前端挑战是处理各种状态:浏览器支持检测、身份验证器可用性、用户取消和错误恢复。并非每个浏览器都支持所有功能。并非每个设备都有平台身份验证器。您的 UI 需要为每种情况提供优雅的降级方案。

跨设备身份验证

最吸引人的密码键功能之一是跨设备身份验证。用户可以通过手机扫描二维码在台式计算机上进行身份验证。手机的密码键对挑战进行签名,桌面浏览器通过蓝牙低功耗(BLE)邻近检查接收结果。

这在实践中效果良好,但存在边缘情况。BLE 要求意味着两台设备都需要启用蓝牙并保持邻近。限制蓝牙的企业网络可能会造成干扰。而且,二维码流程虽然功能正常,但不如同一设备上的直接生物识别认证快。

不完善之处

密码键并非完美,假装它们完美无缺对开发者没有帮助。以下是真实存在的问题:

平台锁定问题。如果用户仅在 Apple 设备上创建密码键,这些密码键不会同步到他们的 Android 手机。跨平台密码键可移植性正在改善——FIDO 联盟在 2025 年底发布了凭据交换规范——但目前还不是很无缝。使用混合生态系统的用户可能需要在多个平台上拥有密码键。

账户恢复。当用户无法访问所有设备时会发生什么?使用密码,您可以通过电子邮件重置。使用密码键,恢复更困难,因为没有”知识因素”可以依赖。您需要强大的恢复流程——通常涉及基于电子邮件的恢复链接,引导用户创建新的密码键,或存储在安全位置的备份安全密钥。

企业复杂性。企业环境中的托管设备增加了复杂性。IT 部门需要控制允许哪些身份验证器、密码键是否可以同步,以及凭据生命周期管理如何工作。密码键的 MDM(移动设备管理)集成故事仍在成熟中。

共享设备场景。密码键与设备上的用户身份绑定。在共享计算机上——图书馆信息亭、家庭台式机——体验与个人设备不同。跨设备二维码身份验证很好地处理了这种情况,但它比直接生物识别认证慢。

迁移策略

您不能一夜之间切换到无密码。实际的迁移路径如下:

  1. 第一阶段:将密钥作为选项提供,与现有身份验证方式并存。允许用户创建密钥,但不移除密码。跟踪采用指标。
  2. 第二阶段:将密钥作为首选方法推广。在登录时显示密钥提示。在密码更改时提供密钥设置。将无密码流程设为新账户的默认选项。
  3. 第三阶段:激励迁移。减少密钥用户的使用摩擦。为基于密码的登录添加额外的验证步骤。考虑减少钓鱼风险等安全优势作为卖点。
  4. 第四阶段:弃用密码。对于可行的应用程序,使密钥成为新账户的唯一选项。现有用户保留密码访问权限,并有迁移提示。

到2026年,大多数应用程序应该处于第一阶段或第二阶段。完全消除密码仅对拥有受控用户群体的应用程序是可行的——内部工具、新的消费产品、开发者平台。

安全案例

除了可用性,密钥从根本上提高了安全性。它们在设计上具有抗钓鱼特性——凭证绑定到来源(域名),因此为example.com创建的密钥无法在examp1e.com上进行身份验证。没有可窃取的共享密钥,没有可入侵的密码数据库,也没有可在多个站点重复使用的凭证。

对于处理敏感数据的应用程序,密钥比您可以做的任何其他单一变更更能减少攻击面。仅消除钓鱼作为可行攻击向量这一项就足以证明实施工作的合理性。

关键要点

  • 密钥在2026年已可用于生产环境,并且所有主要平台都支持该技术。该技术已足够成熟,可供主流采用。
  • 从将密钥作为可选身份验证方法开始,与密码并存。跟踪采用情况,收集反馈,并在将密钥设为默认之前进行迭代。
  • 规划恢复和边缘情况——跨平台可移植性、设备丢失、共享设备和企业管理。这些问题是可以解决的,但需要精心设计。
  • 安全优势是巨大的。密钥通过设计消除了钓鱼、凭证填充和密码数据库泄露。
  • 使用成熟的库(SimpleWebAuthn、py_webauthn),而不是从头实现WebAuthn协议。加密细节相当复杂,错误是危险的。

By Michael Sun

Founder and Editor-in-Chief of NovVista. Software engineer with hands-on experience in cloud infrastructure, full-stack development, and DevOps. Writes about AI tools, developer workflows, server architecture, and the practical side of technology. Based in China.

Leave a Reply

Your email address will not be published. Required fields are marked *

You missed