← 中文资源

简体中文版本

用 WebAuthn 注册通行密钥

实现 WebAuthn 注册流程,保存凭证公钥与计数器,登录时校验断言,全程不存储任何共享秘密。

阅读英文原文

概述

通行密钥把认证从共享秘密换成保管在认证器中的密钥对,服务端只保存公钥,从而免于离线撞库。实现难点在于正确处理挑战、证明与计数器,并规划好账户恢复。

关键步骤

  1. 服务端生成注册挑战并把选项传给浏览器。
  2. 客户端调用 navigator.credentials.create 并把证明发回。
  3. 校验证明并保存凭证 id、公钥与计数器。
  4. 登录时校验断言并检查计数器是否递增。

验证

  • 服务端从不保存共享秘密。
  • 每次认证绑定新鲜挑战。
  • 计数器递减的异常被标记。
  • 用户可注册多个认证器。

注意事项

  • 通行密钥需要安全上下文与兼容认证器,仍需为部分用户保留回退方案。
  • 当所有认证器丢失时账户会被锁死,账户恢复因此至关重要。

适用范围

本条目围绕「用 WebAuthn 注册通行密钥」给出可复制的步骤、验证方式与常见问题,适合需要按此流程落地的工程团队。执行时请结合自身上下文调整命令与阈值,并在变更前后留存证据,便于后续复核与回滚。

const cred = await navigator.credentials.create({
  publicKey: {
    challenge, rp: { name: 'Acme' }, user: { id, name },
    pubKeyCredParams: [{ type: 'public-key', alg: -7 }],
  },
});
await fetch('/webauthn/register/verify', { method: 'POST', body: JSON.stringify(cred) });