WebAuthn 与通行密钥(passkeys)
发布于
一句话: Web Authentication API(WebAuthn)让站点注册并验证一个绑定到设备认证器的 公钥凭据,于是用户用指纹、面容或设备 PIN 登录,而非密码。**通行密钥(passkey)**是一种 可发现的 WebAuthn 凭据,通常会在用户的设备间同步——天生抗钓鱼,因为签名被绑定到站点的源 (origin),且私钥从不暴露给站点。
WebAuthn 究竟做了什么
Section titled “WebAuthn 究竟做了什么”WebAuthn 用一对密钥取代共享密钥(密码)。对于通行密钥(可发现凭据),私钥由认证器 持有(安全元件、TPM 或平台密钥库);而对于某些不可发现的凭据,私钥可能改由依赖方以包装 形式存储,用认证器持有的主密钥加密。无论哪种方式,公钥都由你的服务器存储,私钥从不 交给站点。有两种仪式(ceremony):
- 注册(
navigator.credentials.create())—— 认证器为你的源生成一对新密钥,返回公钥 及一份证明(attestation)。你把公钥与凭据 ID 关联到用户账户存储。 - 认证(
navigator.credentials.get())—— 认证器用私钥对服务器签发的挑战 (challenge)进行签名。你的服务器用存储的公钥验证签名。
由于被签名的数据包含源与一个全新挑战,在仿冒域名上钓取到的凭据毫无用处,捕获的断言也无法 被重放。
通行密钥 vs “经典” WebAuthn
Section titled “通行密钥 vs “经典” WebAuthn”通行密钥是一种可发现(也叫驻留,resident)的 WebAuthn 凭据——认证器存储了足够的状态, 无需服务器先指明凭据 ID 即可找到该凭据。这正是“轻点即可登录”、无需先输入用户名的能力来源。 结合提供方同步(iCloud 钥匙串、Google 密码管理器等),同一个通行密钥可在用户的多台设备上 使用。
| 经典 WebAuthn(第二因素) | 通行密钥 | |
|---|---|---|
| 可发现凭据 | 通常不需要 | 需要(residentKey: "required") |
| 是否先需用户标识 | 常需(用户名 + 密码,再用密钥) | 不需——凭据可发现 |
| 典型角色 | 密码之上的第二因素 | 主要的、无密码登录 |
| 跨设备 | 漫游安全密钥,逐设备 | 在用户设备间同步 |
平台 vs 漫游认证器
Section titled “平台 vs 漫游认证器”- 平台认证器 —— 内建于设备(Touch ID / Face ID、Windows Hello、Android 生物识别)。
用
authenticatorAttachment: "platform"请求它。最适合用户自有设备上的主通行密钥。 - 漫游(跨平台)认证器 —— 可移除的安全密钥(USB/NFC/蓝牙),或用一部手机登录到另一台
设备。对硬件密钥或跨设备流程使用
"cross-platform"。
在提供通行密钥路径前,用
PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() 检测是否存在平台
认证器,并用 isConditionalMediationAvailable() 启用自动填充式的通行密钥建议。
条件式 UI(通行密钥自动填充)
Section titled “条件式 UI(通行密钥自动填充)”以 mediation: "conditional" 调用 navigator.credentials.get(),可让浏览器在用户名
字段的自动填充中内联提供已保存的通行密钥,而非弹出模态框。该请求会静默等待,直到用户选中
一个通行密钥,因此你可以在页面加载时就发起它,又不打扰更愿意打字的用户。为输入框搭配
autocomplete="username webauthn"。
浏览器与生态支持
Section titled “浏览器与生态支持”WebAuthn 在当前主流浏览器上获得支持。通行密钥——具备跨设备同步的可发现凭据——在若干主流
平台上可用,但覆盖仍在补齐:所引的 passkeys.dev 设备支持矩阵记录了各平台的空缺(例如,
在某些平台上,同步通行密钥被列为计划中而非已发布)。在受支持处,同步由平台凭据管理器
(例如 Google 密码管理器或 iCloud 钥匙串)处理,而非仅靠浏览器。由于该矩阵会变动,请特性
检测(PublicKeyCredential、条件式调解)而非假定。
PWA 的职责
Section titled “PWA 的职责”WebAuthn 的安全性取决于服务器端的验证。浏览器 API 交给你的是待校验的数据,而非一个完成的 决定:
- 为每次仪式生成一个加密随机的挑战并绑定到会话;拒绝陈旧或重用的挑战。
- 验证返回的客户端数据中的源与 RP ID 与你的站点匹配。
- 注册时存储公钥、凭据 ID 与签名计数器;每次认证时确认计数器没有倒退(克隆信号)。
- 把通行密钥当作账户凭据:允许用户登记不止一个、为其命名,并撤销丢失的那个。
- 在展示任何通行密钥 UI 前特性检测
window.PublicKeyCredential。 - 用
isUserVerifyingPlatformAuthenticatorAvailable()把守平台通行密钥路径。 - 为真正的通行密钥设置
residentKey: "required"与userVerification: "preferred"。 - 在服务器端签发全新随机挑战,并验证源、RP ID 与签名。
- 持久化并检查签名计数器,以检测被克隆的认证器。
- 在受支持处用
autocomplete="username webauthn"提供条件式 UI 自动填充。 - 允许每账户多个通行密钥并提供恢复路径,使丢失设备不至于锁死账户。