更新记录(仅首版,2026年07月29日 发布)
- 首次发布
引用本文(DOI(已登记存档): 10.5281/zenodo.22175452)
以下 DOI 指向先前登记的存档,内容可能与当前正文不同。引用当前正文时,请使用本页网址。
Go Komura(2026)。《通行密钥为什么安全——图解机制、同步与丢失时的注意事项》。小村软件有限公司。 https://comcomponent.com/zh-CN/blog/passkey-why-secure/
- DOI(已登记存档)
- 10.5281/zenodo.22175452
- DOI(上次登记版本)
- 10.5281/zenodo.22175453
“能用指纹登录,所以安全。”通行密钥有时会被这样介绍,但它的安全性核心并不是指纹或人脸本身,而在于不把私钥交给登录目标,只用签名证明自己持有属于该站点的密钥。1
不过,如果理解成“用了通行密钥就绝不会被接管”“私钥一定不会离开手机”,在同步和丢失时就会做出错误判断。登录机制变强,与设备、恢复手段和登录后的会话也自动变安全,是两件不同的事。
本文从与密码的差异出发,图解注册和登录的流程,依次梳理它为什么能抗钓鱼、同步型与设备绑定型的差异,以及丢失设备时的处理。后半部分讨论在自家 Web 服务或 Windows 业务系统中引入时的检查要点。
图中实线表示始终成立的关系,虚线表示带条件的关系(成立条件写在详情页各关系的说明中)。关系的完整列表(共 38 条,附依据与确信度)以及主要概念的定义,汇总在知识地图详情页(日文)。数据:JSON-LD / Turtle
1. 通行密钥安全的理由有三个
通行密钥是可以代替密码用于登录的基于公钥密码学的凭据。注册时生成的密钥对中,私钥由用户一侧管理,公钥注册到服务一侧。Web 上的注册和认证使用名为 WebAuthn 的标准 API。12
| 安全性的依据 | 通行密钥改变了什么 | 由此推不出的结论 |
|---|---|---|
| 不把私钥交给登录目标 | 即使只有公钥外泄,攻击者也无法生成正确的签名 | 并不意味着服务器的数据外泄就变得无害 |
| 每次登录尝试都验证响应 | 核对与新挑战值绑定的签名,阻止重放过去的响应 | 并不意味着可以省掉挑战值的管理 |
| 限制凭据的使用目标 | 无法从无关的仿冒域名上使用属于真站点的通行密钥 | 并不意味着诈骗和滥用账户恢复流程也随之消失 |
flowchart TB
accTitle: 通行密钥改变的三个认证弱点
accDescr: 对秘密的交付、响应的重放、使用目标的错认,分别用不同的机制来应对。
A["使用通行密钥登录"] --> B["不交出私钥,只返回签名"]
A --> C["核对并消费挑战值"]
A --> D["确认 RP ID 与源"]
B --> E["仅凭公钥无法伪造签名"]
C --> F["不允许重放过去的响应"]
D --> G["不允许在无关的仿冒网站上使用"]
图1:通行密钥的强度在于把密码学、一次性的请求和使用目标的限制组合起来。
本文所说“不发送私钥”,发送的目标指的是所登录服务的服务器。在同步型通行密钥中,另有一条把私钥加密后保管和复制的路径。把这两者分开,就能解开“既然要同步到云端,为什么还说不发送秘密”这个疑问。
另外,服务器除公钥之外还保存凭据的标识符、与账户的对应关系、会话信息等。“仅凭公钥无法冒充”和“数据库不需要保护”并不是一回事。2
2. 长密码和一次性验证码仍留下什么问题
普通的密码认证会把用户输入的密码通过 TLS 保护的通信发送到服务器,由服务器与已保存的哈希等进行核对。合适的加盐哈希和足够的计算开销,会让保存数据外泄后反复猜测的攻击变得困难。随机、够长且不重复使用的密码同样有意义。3
如果在多个服务上重复使用同一个密码,攻击者就可能用从一处泄露的账号与密码组合去尝试其他网站,也就是“撞库攻击”,从而把危害扩散到其他账户。即使密码很长,只要重复使用,就无法阻止这种扩散。4
即便如此,用户仍然可能把正确的密码交给错误的对象。只要在攻击者准备的网站上输入了真密码,即使该网站的 TLS 证书本身没问题,输入的值也会送到攻击者手里。这不是 TLS 被攻破,而是搞错了正在与之安全通信的对象。
sequenceDiagram
accTitle: 向仿冒网站的输入无法仅靠 TLS 阻止
accDescr: 用户在仿冒网站输入的密码和验证码,即使走加密通信,也会送到仿冒网站的运营者手中。
participant U as 用户
participant P as 仿冒网站
participant S as 真正的服务
U->>P: 输入真密码
P->>S: 转发收到的密码
S-->>P: 要求追加认证
P-->>U: 要求一次性验证码
U->>P: 输入验证码
P->>S: 在有效期内转发验证码
S-->>P: 验证通过后签发会话
图2:这是把密码和验证码实时转发的 AiTM 型钓鱼的概要。
TOTP 是认证应用与服务器共享同一个种子、按时间生成验证码的方式。它并不会在每次登录时发送种子本身。但用户输入的验证码并没有与正规站点的域名绑定,因此在有效期内仍有被仿冒网站转发的空间。短信验证码同样存在能被输入到仿冒网站的问题。3
这并不是说多因素认证没有意义。与只用密码的认证相比,它能挡住的攻击更多。在此基础上,面对连手动输入验证码都要利用的攻击,转向 FIDO/WebAuthn 这类具备抗钓鱼能力的认证是有意义的。5
用密码管理器生成强密码、只在正确的域名上自动填充,也是有效的对策。但用户仍然可以把那个密码复制出来,粘贴到别的输入框里。通行密钥的不同之处在于,用户仅靠自己的操作无法解除这种使用目标的限制。
3. 注册和登录时来回传递的是什么
注册时生成密钥对并与账户绑定
处理通行密钥的角色大致有三个:服务一侧的 RP(Relying Party,依赖方)、提供 WebAuthn 的浏览器和操作系统,以及负责生成和使用密钥的认证器。认证器既有与操作系统功能或凭据管理器联动的,也有外接的 FIDO2 安全密钥等。人脸或指纹的核对,是为了许可对它的使用而进行的处理。26
sequenceDiagram
accTitle: 通行密钥注册的流程
accDescr: 根据注册请求生成密钥对,服务验证注册响应后,把公钥和凭据 ID 与账户绑定。
participant S as 服务
participant B as 浏览器与操作系统
participant A as 认证器
S->>B: 挑战值与账户信息
B->>B: 确认使用目标
B->>A: 请求创建凭据
A->>A: 本人验证与生成密钥对
A-->>B: 公钥与凭据 ID 等
B->>S: 发送注册响应
S->>S: 验证注册响应
S->>S: 把凭据注册到账户
图3:注册的不只是公钥,而是包含标识符和验证用数据的响应。私钥不会发送给登录目标。
credential ID(凭据 ID)是用于识别具体是哪个通行密钥的值。服务器会把它与公钥和账户对应起来保存。向既有账户添加新的通行密钥时,先用既有方式确认操作者确实是该账户的用户,必要时要求重新认证。不能仅凭浏览器发来的用户名决定注册到哪个账户。67
通常在向其他服务或其他账户注册时会生成另一个密钥对,所以用户不需要做相当于重复使用密码的事。但它并不是一种能阻止通过邮箱地址等其他信息关联用户的机制,也不意味着“用了通行密钥就变成匿名”。
登录时返回针对本次请求的签名
登录时,服务器会签发难以预测的随机数,即挑战值。认证器用私钥生成签名,浏览器把它返回给服务器。服务器用已注册的公钥验证,并确认它是否是对本次签发的请求的正确响应。6
sequenceDiagram
accTitle: 通行密钥登录的流程
accDescr: 认证器生成与本次请求绑定的签名,服务器验证签名、挑战值、使用目标和账户。
participant S as 服务
participant B as 浏览器与操作系统
participant A as 认证器
S->>B: 未使用的挑战值与 RP ID
B->>B: 确认使用目标是否合规
B->>A: RP ID 与数据的哈希
A->>A: 用生物识别或 PIN 确认
A->>A: 用私钥签名
A-->>B: 认证器数据与签名
B->>S: 凭据 ID 与认证响应
S->>S: 验证响应与账户
S-->>B: 仅在成功时签发会话
图4:登录的响应是“持有私钥的证明”,而不是私钥本身。
更准确地说,认证时的签名对象是下面这些数据。|| 表示字节序列的连接。8
签名对象 = authenticatorData || SHA-256(clientDataJSON)
clientDataJSON:
type 认证时为 webauthn.get
challenge 服务器签发的挑战值
origin 调用方的源
authenticatorData:
rpIdHash RP ID 的 SHA-256 哈希
flags 用户在场和用户验证等的结果
signCount 签名计数器
“对挑战值签名”是为了把握整体而做的简化说明。实际上使用目标和认证器的状态也参与签名的验证。另一个要点是角色分工:并不是认证器去读取网页来判断源,而是它接收浏览器收集好的客户端数据的哈希。
flowchart TB
accTitle: 认证时与签名绑定的数据
accDescr: 把包含挑战值和源的客户端数据的哈希,与包含 RP ID 哈希等的认证器数据连接起来后签名。
A["挑战值与源等"] --> B["clientDataJSON 的哈希"]
C["RP ID 的哈希与标志位等"] --> D["authenticatorData"]
B --> E["连接认证器数据与哈希"]
D --> E
E --> F["用私钥签名"]
图5:不仅是挑战值,使用目标和认证器的状态也参与签名的验证。
过去的签名之所以不能被重放,不是因为签名本身会随时间消失,而是因为服务器把挑战值绑定到具体的登录尝试上、设定了有效期,并且不再接受已经使用过的请求。仅仅通过公钥完成签名验证,还不足以构成允许登录的条件。
4. 为什么在与真站点几乎一样的仿冒网站上也用不了
RP ID 与源的作用不同
RP ID 是决定凭据作用范围的域名,通常写成 example.com 这样的形式。而源是方案、主机和端口的组合。例如可以是这样的构成:源为 https://login.example.com,RP ID 为 example.com。9
按通常的域名关系验证,login.example.com 的页面可以把 RP ID 指定为 example.com。但无关的 examp1e.com 页面无法通过指定 example.com 来使用属于真站点的通行密钥。判断依据不是外观是否相似,而是浏览器会验证使用目标之间的域名关系。
flowchart TB
accTitle: 通过 RP ID 限制凭据的使用目标
accDescr: 对于具有正规域名关系的页面和无关的仿冒网站,在请求真实 RP ID 时浏览器的判断不同。
A["把 RP ID 指定为 example.com"] --> B{"调用方是哪里"}
B -->|"login.example.com"| C["满足域名关系的条件"]
B -->|"examp1e.com"| D["属于无关域名,予以拒绝"]
C --> E["用对应的通行密钥继续认证"]
E --> F["服务器也验证是否为已许可的源"]
D --> G["无法使用属于真站点的通行密钥"]
图6:浏览器的使用目标限制和服务器的源验证,共同支撑抗钓鱼能力。
服务器一侧也要验证随签名返回的 origin 是否属于已许可的源,以及 rpIdHash 是否为期望的 RP ID 的哈希。不能把用仿冒网站自己的 RP ID 生成的密钥,或来自未许可源的响应,当作对真实账户的认证而予以接受。8
另外,WebAuthn Level 3 还提供了 Related Origin Requests,用于在服务一侧明确关联的其他源上使用同一个 RP ID。因此“主机名不完全一致就一定用不了”这种说法也不准确。重要的是把凭据的使用限制在服务所认可的范围之内。即使使用关联源,也不等于可以把服务器的许可列表无限扩大。9
“抗钓鱼”不等于能抵抗一切诈骗
到这里的说明都以浏览器、操作系统和认证器可信,并且服务器执行了必要的验证为前提。正规站点被入侵、设备上的恶意软件、薄弱的账户恢复流程,都不是单靠 WebAuthn 就能解决的。
也可能出现这种情况:仿冒网站提示“通行密钥当前不可用,请输入密码和短信验证码”,把用户引向另一条登录路径。通行密钥擅长防止把真实凭据交给仿冒网站这类问题,但并不意味着用户今后完全不需要留心。5
5. 指纹、人脸和 PIN 不是发给服务器的密码
使用通行密钥时之所以要求指纹或人脸,是为了确认使用私钥的操作确实得到了该设备合法用户的许可。这个处理称为用户验证(User Verification,UV)。WebAuthn 的认证响应不会携带指纹图像或人脸特征值发送给登录目标。12
flowchart TB
accTitle: 设备上的本人验证与服务端的签名验证
accDescr: 指纹、人脸和 PIN 用在用户一侧,用于许可密钥的使用;服务一侧确认的是签名和验证结果,而不是生物特征信息。
A["用指纹、人脸或 PIN 确认"] --> B["认证器许可使用私钥"]
B --> C["生成带签名的认证响应"]
C --> D["服务用公钥验证"]
D --> E["同时确认所要求的用户验证结果"]
图7:设备的解锁与向服务的认证相互配合,但服务器并不核对指纹或 PIN。
也许有人会觉得,既然 PIN 也能用,那不就和密码一样吗。区别在于这个 PIN 与什么进行核对。这里的 PIN 是用来许可使用认证器的,并不是网站为全体用户保存、每次登录时都要接收的密码。在设计得当的认证器上,还会有输错次数限制等机制生效。3
不过,如果设备被盗,而且解锁方式也被对方掌握,攻击者能够使用通行密钥的风险就会上升。不能因为改用了人脸识别,就认为设备的锁屏密码可以设得很简单。另外,表示触摸屏幕等动作的用户在场(User Presence,UP),与通过生物识别或 PIN 完成的 UV 是不同的标志位。实现方要按需要求 UV,并在响应中加以确认。
6. 同步型与设备绑定型要守护的位置不同
通行密钥分为在设备之间同步的,以及绑定到特定认证器的两类。两者都在不把私钥交给登录目标的前提下完成认证,但密钥的保管、复制和恢复方式不同。10
| 对比项 | 同步型通行密钥 | 设备绑定型通行密钥 |
|---|---|---|
| 私钥的处理方式 | 通过保管库在设备之间复制 | 保存在特定认证器中,不做同步 |
| 典型例子 | 保存到 iCloud 钥匙串、Google 密码管理器等 | FIDO2 安全密钥、保存在 Windows Hello 本地容器中的凭据等 |
| 换机或故障 | 满足同步与保管库的恢复条件时,在其他设备上也能使用 | 需要另外注册的密钥或账户恢复手段 |
| 管理上的重点 | 同步账户、保管库的解锁条件、加入同步的设备 | 认证器的保管、备用密钥、吊销流程 |
| 硬件保护 | 因产品和设备而异 | 仅凭“设备绑定型”这个分类,并不能确定保护强度 |
flowchart TB
accTitle: 同步与登录是不同的路径
accDescr: 同步型通过加密的保管库复制密钥,但无论同步型还是设备绑定型,发送给登录目标的都是认证响应。
V["加密的同步保管库"] <-->|"同步与恢复"| A["设备 A 上的同步型通行密钥"]
V <-->|"同步与恢复"| B["设备 B 上的同一个通行密钥"]
A -->|"带签名的响应"| S["作为登录目标的服务"]
B -->|"带签名的响应"| S
K["设备绑定型的认证器"] -->|"带签名的响应"| S
图8:把复制私钥的同步路径与向服务登录的路径分开,就能理解两者的差别。
在 Apple 和 Google 的机制中,会同步的通行密钥由端到端加密保护。其设计并不允许服务提供方直接读取云端保存的数据来取得私钥。1112
另一方面,要在新设备上恢复,除了登录同步账户之外,有时还需要以前设备的锁屏密码或保管库 PIN 等。具体条件因产品和配置而异。既不能说“只凭云账户的密码就能恢复全部通行密钥”,也不能说“只要拿回云账户就一定能恢复”。1113
在同步型中,一旦保管库的解锁手段、恢复手段乃至加入同步的设备一并被攻破,影响就可能扩散到多个服务。因此同步账户的多因素认证、强度足够的设备锁屏、恢复渠道的管理都很重要。若服务支持,还可以考虑用物理安全密钥来加固。但如果连用于恢复的密钥也只放在同一台设备或同一个保管库里,就变成了会一起丢失的配置。
组织的保障级别也需要注意。在 NIST SP 800-63B-4 中,可同步的认证器在满足条件时可用于 AAL2,但不能用于不允许导出私钥的 AAL3。反过来,设备绑定型也不会自动达到 AAL3,还需要满足硬件保护等其余要求。1415
用二维码借助手机登录,与同步不是一回事
还有一种方式:用手机扫描 PC 上显示的二维码,再用该手机上的通行密钥完成登录。FIDO 的跨设备认证会通过蓝牙等确认两台设备彼此靠近,并在手机一侧完成认证。这并不是把手机上的私钥复制到 PC 的操作。161
flowchart TB
accTitle: 用手机上的密钥登录另一台 PC 的流程
accDescr: 用手机扫描 PC 上的二维码,经过靠近确认和手机上的用户验证后完成认证。这个流程不会把私钥复制到 PC。
A["在 PC 的登录界面显示二维码"] --> B["用手机扫描二维码"]
B --> C["确认两台设备彼此靠近"]
C --> D["在手机上完成用户验证与签名"]
D --> E["服务验证认证响应"]
E --> F["在 PC 上登录成功"]
图9:跨设备认证把手边的手机当作认证器使用,不会把密钥复制到 PC。
即使 PC 的同步账户与手机不同,有时也能这样使用,但它并不能在保存密钥的手机丢失时充当备用手段。请把“能从 PC 登录”和“PC 上也注册了独立的通行密钥”区分开。
7. 手机丢失时,要分别停掉设备、凭据和会话
丢失时,先从安全的设备安排远程锁定等措施,如果怀疑已被滥用,要尽快联系服务方或组织的对接窗口。同时确认能否用备用通行密钥或恢复手段进入账户。不必等到恢复完成之后再上报丢失或申请停用。设备的保护、同步账户的保护和服务一侧的吊销,各自的作用不同。1718
flowchart TB
accTitle: 设备丢失时需要分开确认的事项
accDescr: 在推进丢失设备的保护和联系对接窗口的同时,确认安全的恢复手段。通行密钥的吊销与既有会话的终止要分别执行。
A["设备丢失"] --> B["远程锁定等措施与联系对接窗口"]
A --> C["确认备用密钥与恢复手段"]
B --> D["停用有风险的通行密钥"]
C --> E["用安全的设备进入管理界面"]
D --> F["另行终止既有会话"]
E --> F
F --> G["确认同步目标与已注册的认证方法"]
G --> H["在安全环境中准备新密钥与备用密钥"]
图10:停用设备、吊销通行密钥、终止已登录状态,是三件不同的处理。
如果是设备绑定型,可以在服务一侧吊销丢失认证器上的凭据,改用另外注册的备用凭据,这样就能把两者划分开。而在同步型中,多台设备上的副本在服务看来是同一份凭据,因此一旦在服务一侧删除该凭据,其他设备上的副本也无法再登录同一个服务。服务一侧未必能只针对某一台设备上的副本单独吊销。102
远程擦除也不一定在设备离线时立刻生效。在 Apple 的“查找”中,离线设备的擦除要等它下次联网时才开始。19仅凭把设备从同步账户中移除,就断定该设备上的私钥副本一定无法再使用,是危险的。如果担心被滥用,就需要判断并尽快在各个服务一侧停用、吊销相应的凭据。若无法登录,则使用官方窗口,并同时确认让合法用户恢复访问的手续。
另外,删除通行密钥也不一定会因此终止所有既有会话。要另行确认服务是否提供“从所有设备退出登录”之类的功能,同时检查是否有可疑的通行密钥或恢复渠道被添加进来。2018
在丢失之前,最好先查清重要服务是否支持注册多个通行密钥,注册一份独立的备用凭据并实际试着登录一次,这样更放心。靠同步让同一把密钥出现在两台设备上固然方便,但这与另外再注册一把密钥并不相同。在删除最后一种登录手段之前,请连恢复代码的保管位置一起确认,确保还有回得去的途径。
8. 用了通行密钥之后仍然残留的弱点在哪里
通行密钥强化了认证中的关键部分,但进入账户的路径并不只有常规的登录界面。引入时,除了关注“使用通行密钥的人是否变多”,还要检查下面这些路径。
flowchart TB
accTitle: 引入通行密钥后仍然残留的攻击路径
accDescr: 除通行密钥登录之外,薄弱的替代手段、恢复手续、设备与保管库、既有会话仍然是攻击目标。
B["薄弱的备用登录方式"] --> A["对账户的非法访问"]
C["滥用恢复手续"] --> A
D["设备与保管库被入侵"] --> A
E["滥用会话"] --> A
图11:即使常规的通行密钥登录足够强,其他入口和登录后的状态仍需单独防护。
备用登录方式。如果只用密码或短信也能完成同样的操作,攻击者就会瞄准那一侧。不过,在确认备用手段和恢复路径之前一次性全部停用,也会把合法用户挡在门外。应先备好支持的设备、备用密钥和支持流程,再缩小范围、分阶段地收敛。5
账户恢复与添加密钥。如果仅凭“设备坏了”这样的申报就放松本人验证,就会形成让攻击者注册自己通行密钥的通道。对重要账户,要把恢复申请的核实、增删认证方法时的重新认证、变更通知和审计组合起来。仅发出通知并不能阻止未经批准的注册,因此注册之前的核实是必要的。18
设备与同步保管库。操作系统和浏览器的更新、设备锁屏、掌握有哪些设备加入了保管库,这些工作仍然必要。通行密钥并不是把不安全的 PC 变成安全 PC 的功能。在共用设备上,还要确认当前配置允许谁使用这些凭据。
会话。如果常见的会话 Cookie 被窃取并且仍可使用,攻击者有时无需再做一次通行密钥认证就能操作。Secure、HttpOnly、合适的 SameSite、有效期、重新认证、服务器端吊销等要另行设计。HttpOnly 限制 JavaScript 读取 Cookie,但并不能阻止通过 XSS 滥用已登录状态进行操作。20
9. 在自家 Web 服务中引入时的要点
只调用 API,并不等于登录功能就实现完了
WebAuthn 的注册 API 是 navigator.credentials.create(),认证 API 是 navigator.credentials.get()。FIDO2 由 WebAuthn 和 CTAP 组成,CTAP 是规定客户端与外接安全密钥等认证器之间交互的规范。Web 服务的实现者不需要自己实现 USB 或蓝牙层面的通信。21
| 术语 | 主要作用 |
|---|---|
| 通行密钥 | 代替密码使用的凭据 |
| WebAuthn | 从 Web 创建和使用凭据的 API,以及相应的验证步骤 |
| CTAP | 客户端与认证器之间的交互 |
| FIDO2 | 把 WebAuthn 与 CTAP 组合起来的标准框架 |
flowchart TB
accTitle: Web 服务中通行密钥实现的职责分工
accDescr: 服务器负责签发请求和验证,浏览器提供 API,认证器负责使用密钥。
S["服务器:签发请求与验证响应"] <-->|"请求与响应"| B["浏览器:WebAuthn API"]
B <--> O["与操作系统和凭据管理器的联动"]
B <-->|"CTAP 等"| A["外接认证器"]
图12:浏览器一侧的调用,与服务器一侧的验证和账户管理,要成套实现。
下面是展示传给 API 的值放在什么位置的浏览器一侧骨架。仅凭这段片段无法完成注册和登录。registrationOptions 和 authenticationOptions 是服务器为本次尝试生成的值;challenge、user.id、凭据 ID 等二进制项目,不能保持 JSON 中的 Base64URL 字符串形式,而应已经转换为合适的字节序列。2
// 从注册按钮的操作调用。选项由服务器签发并保存。
async function createPasskey(registrationOptions) {
if (!window.isSecureContext || !window.PublicKeyCredential) {
throw new Error("当前环境无法使用通行密钥。");
}
const credential = await navigator.credentials.create({
publicKey: registrationOptions,
});
if (!credential) throw new Error("通行密钥的注册未能完成。");
return credential;
// 由调用方把注册响应序列化后发送给服务器。
// 在服务器验证成功之前,不要显示为注册已完成。
}
// 从登录按钮的操作调用的常规认证流程。
async function usePasskey(authenticationOptions) {
if (!window.isSecureContext || !window.PublicKeyCredential) {
throw new Error("当前环境无法使用通行密钥。");
}
const assertion = await navigator.credentials.get({
publicKey: authenticationOptions,
});
if (!assertion) throw new Error("通行密钥的认证未能完成。");
return assertion;
// 由调用方把认证响应序列化后发送给服务器。
// 由服务器验证,仅在成功时创建会话。
}
在实际界面中,要在调用方处理被拒绝的 Promise,并向用户提示取消、超时、环境不受支持等情况。注册响应的二进制转换和通信,使用所选库中相应的 API 可以减少实现遗漏。
注册选项中的 authenticatorSelection.residentKey: "required",用于要求可选择账户使用的可发现凭据。如果设计上必须经过生物识别或 PIN 确认,则注册时指定 authenticatorSelection.userVerification: "required",认证时指定 userVerification: "required"。user.id 应是服务器签发的最长 64 字节的不透明标识符,不要直接使用邮箱地址,并且要与显示名区分开。7
如果要使用把通行密钥作为登录框自动填充候选项呈现的 Conditional UI,先用 PublicKeyCredential.isConditionalMediationAvailable() 确认是否受支持,再把 mediation: "conditional" 与输入框的 autocomplete="username webauthn" 组合使用。对不受支持的环境,要保留上面那种从按钮触发的常规流程。22
先设计好服务器要验证的项目
密码学部分的验证,可以借助库来完成:Node.js 有 SimpleWebAuthn,.NET 有 fido2-net-lib 等。不过,有了库并不意味着与账户的绑定和恢复设计也会自动变得安全。2324
| 要确认的对象 | 实现中要定下来的事 |
|---|---|
| 挑战值 | 用密码学安全的随机数生成,绑定到具体尝试和会话,并保证有效期和只消费一次 |
type |
注册为 webauthn.create、认证为 webauthn.get,拒绝两者混用 |
origin |
在服务器一侧配置可信的源,不要根据请求内容自行生成许可列表 |
rpIdHash |
与期望的 RP ID 的 SHA-256 进行核对 |
| 凭据与账户 | 确认 credential ID 与 userHandle 的对应关系,不要仅凭另外输入的用户名决定登录到哪个账户 |
| 标志位与签名等 | 按规范验证所需的 UP 与 UV、备份状态的一致性、许可的算法以及签名 |
| 注册响应 | 确认与请求的对应关系、凭据 ID 是否重复,并按需确认证明(attestation)的可信性 |
| 添加、删除与恢复 | 设计既有用户的重新认证、CSRF 防护、备用密钥、变更通知与审计 |
这个表是实现时的检查视角,不能代替规范中规定的验证步骤。如果要使用 iframe 或关联源等,还要连同它们的附加条件一起确认。在常规的显式认证中要确认 UP;如果把 UV 设为必需,还要确认响应中的 UV。78
flowchart TB
accTitle: 服务器一侧的认证判定
accDescr: 在确认与本次请求的对应关系、使用目标、凭据的所有者、签名和策略之后,才签发会话。
A["收到认证响应"] --> B{"是否与本次未使用的请求一致"}
B -->|"是"| C{"使用目标与所属账户是否正确"}
C -->|"是"| D{"签名与所需的验证结果是否正确"}
D -->|"是"| E["只消费一次请求并签发会话"]
B -->|"否"| X["拒绝认证"]
C -->|"否"| X
D -->|"否"| X
图13:既要确认签名正确,也要确认本次确实可以让该账户登录。
signCount 也不是万能的克隆检测器。有些认证器不维护计数器而返回 0,数值不单调递增的原因也不止复制一种。要确认所采用环境(包括同步型)以及所用库对它的处理方式,把异常值用于风险判断。应避免“不大于上次就一定是克隆”“为 0 就安全”这类一刀切的判断。8
在验证环境中,要把 WebAuthn 的安全上下文要求和 RP ID 的要求分开确认。通常需要 HTTPS,开发时可以使用 http://localhost。http://127.0.0.1 被视为可信的源,和能否把 IP 地址用作 RP ID,是两件不同的事。WebAuthn 的 RP ID 有域名方面的条件,因此开发阶段也请使用 localhost 等所用浏览器能够接受的配置来验证。在那里创建的凭据无法原样带到生产域名上使用。925
10. 在 Windows 和企业内部系统中要确认什么
在 Windows 上,重要的是不要仅凭“弹出了 Windows Hello 界面”这一观察,就判断通行密钥的保存位置以及是否同步。Windows Hello 进行的用户验证,与保存、同步到 Microsoft 或第三方凭据管理器,是要分开确认的项目。既有保存在本地的通行密钥,也有保存在同步提供程序中的通行密钥。26
flowchart TB
accTitle: 在 Windows 上部署通行密钥时的确认顺序
accDescr: 依次分别确认登录对象、凭据的保存位置、组织的许可策略以及丢失时的恢复。
A["要登录到什么"] --> B["区分 Web 服务、Entra ID 与 Windows"]
B --> C["确认通行密钥的保存位置与是否同步"]
C --> D["确认身份验证方法策略与身份验证强度"]
D --> E["验证备用密钥与丢失时的流程"]
图14:即使弹出的是同一个 Windows Hello 界面,登录对象和保存位置不同,其运维含义也不同。
保存在 Windows Hello 本地容器中的凭据,与同步型的保管库不同。在使用 TPM 的 Windows Hello 配置中,由 TPM 提供的密钥保护承担着重要作用。不过,不要把通行密钥的一般分类与是否使用 TPM 等同看待,而应依据实际的保存位置、设备和组织要求来判断。2728
在 Microsoft Entra ID 中,要把许可使用通行密钥的身份验证方法策略,与规定目标资源需要何种强度认证的条件访问身份验证强度分开设计。仅仅把状态改成可以注册通行密钥,并不会让所有访问自动限定为抗钓鱼 MFA。包括同步型在内,允许哪些类型的通行密钥,要依据最新的支持情况和组织策略来确认。29
如果要让企业内部 Web 应用直接支持 WebAuthn,先把 HTTPS、证书、名称解析,以及能作为稳定 RP ID 的域名准备好。如果采用把处理委托给认证平台的架构,应用一侧则要设计与该平台的联动和会话管理。在 WinForms/WPF 应用中使用 Entra ID,与应用本身成为 WebAuthn 的 RP,也不是一回事。
另外,通行密钥并不是一种会自动替换 SMB 共享身份验证、或直接修好 NTLM、Kerberos 问题的功能。先确定要改变的是哪种登录,再从一个小范围的对象开始试验注册、认证、丢失和恢复,这样才能在不中断业务的前提下完成引入。
11. 总结——不交出秘密与守护周边,必须成套进行
通行密钥的强度在于:不把私钥交给登录目标,而用与本次请求和使用目标绑定的签名完成认证。仅靠公钥外泄无法生成正确的签名,也无法从无关的仿冒网站上使用属于真站点的凭据。
另一方面,同步型的保管库、设备锁屏、备用登录方式、恢复流程以及登录后的会话,仍然需要持续防护。把改用通行密钥后不再需要的对策,与仍然必要的对策区分开,才是正确评估引入效果的视角。
作为使用者,要确认保存位置和恢复手段,为重要账户准备独立的备用凭据。作为引入方,要把服务器端的验证、多个通行密钥的管理、吊销与恢复当作一个整体功能来设计。把这些都纳入进来,才能把便利性和抗钓鱼能力真正落到实际运维中。
相关文章
- Windows 的 TPM 是什么——图解“不外泄密钥的保险柜”与度量启动
- 图解 NTLM 与 Kerberos——为什么认证会“回退”到 NTLM
- 在 WinForms/WPF 应用中集成 Entra ID 认证——MSAL.NET 与 WAM Broker 的实务架构
- PowerShell 中凭据的安全处理方式——把明文密码逐出脚本
- Windows 应用程序开发的安全最低限度检查清单
- 中小企业的安全对策,该从何入手——IPA《中小企业信息安全对策指南》第 4.0 版导读
相关咨询领域
合同会社小村软件承接包括企业内部 Web 系统认证功能改造、与 Entra ID 的对接,以及在 WinForms/WPF 等 Windows 业务应用中集成认证在内的受托开发。在评估是否支持通行密钥时,我们也会把使用的设备、既有认证平台和恢复流程与登录界面一起梳理。
参考链接
规范和产品信息的确认时间为 2026 年 9 月 8 日。可用的功能会因浏览器、操作系统和租户的配置而不同。
-
FIDO Alliance, Passkeys与How Passkeys Work。关于通行密钥的定位、基于公钥密码学的认证以及生物特征信息的处理。 ↩ ↩2 ↩3 ↩4
-
W3C, Web Authentication: An API for accessing Public Key Credentials – Level 3。关于凭据、认证器、API 以及安全上的前提。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
NIST, SP 800-63B-4 — Authenticator and Verifier Requirements。关于密码、OTP、本地解锁信息以及抗钓鱼能力。 ↩ ↩2 ↩3
-
OWASP, Credential Stuffing Prevention Cheat Sheet。关于利用从其他站点泄露的账号与密码组合发起的攻击及其对策。 ↩
-
CISA, More than a Password。关于针对传统 MFA 的攻击,以及向 FIDO/WebAuthn 等抗钓鱼 MFA 的迁移。 ↩ ↩2 ↩3
-
FIDO Alliance Passkey Central, How Passkeys Work。关于注册、认证以及凭据管理器的作用。 ↩ ↩2 ↩3
-
W3C, WebAuthn Level 3 — Registering a New Credential。关于注册响应、凭据 ID、证明(attestation)以及与账户绑定的验证。 ↩ ↩2 ↩3
-
W3C, WebAuthn Level 3 — Verifying an Authentication Assertion。关于签名对象,以及挑战值、源、RP ID、标志位、账户对应关系和签名计数器的验证。 ↩ ↩2 ↩3 ↩4
-
W3C, WebAuthn Level 3 — Relying Party Identifier与Related Origin Requests。关于 RP ID 的域名约束以及关联源的显式处理方式。 ↩ ↩2 ↩3
-
FIDO Alliance Passkey Central, Passkey Types。关于同步型与设备绑定型在保管和使用上的差异。 ↩ ↩2
-
Apple, About the security of passkeys。关于 iCloud 钥匙串的端到端加密以及恢复过程的保护。 ↩ ↩2
-
Google Security Blog, Security of Passkeys in the Google Password Manager。关于私钥同步时的加密以及解锁条件。 ↩
-
Google for Developers, Passkey support on Android and Chrome。关于 Google 密码管理器支持的环境,以及通行密钥的使用和恢复条件。 ↩
-
NIST, SP 800-63B-4 — Syncable Authenticators。关于可同步认证器的保护,以及在 AAL2 与 AAL3 中的处理。 ↩
-
NIST, SP 800-63B-4 — Authentication Assurance Levels。关于 AAL3 要求的不可导出私钥、硬件保护等条件。 ↩
-
FIDO Alliance Passkey Central, Cross-Device Sign-In。关于把手机上的通行密钥用于其他设备登录的机制。 ↩
-
Apple, Use Lost Mode in Find Devices on iCloud.com。关于锁定丢失设备以及官方的处理手续。 ↩
-
NIST, SP 800-63B-4 — Authenticator Event Management。关于认证器的添加、丢失与吊销,以及账户恢复和变更通知。 ↩ ↩2 ↩3
-
Apple, Erase a device in Find Devices on iCloud.com。关于离线设备远程擦除的执行时机。 ↩
-
OWASP, Session Management Cheat Sheet。关于会话的保护与吊销、Cookie 属性,以及 XSS 对策所覆盖的范围。 ↩ ↩2
-
FIDO Alliance Passkey Central, User Authentication Specifications。关于 FIDO2、WebAuthn 与 CTAP 之间的关系。 ↩
-
SimpleWebAuthn, Browser package。关于注册与认证的浏览器侧处理以及 Conditional UI。 ↩
-
SimpleWebAuthn, Server package。关于注册与认证响应的验证,以及应用侧需要管理的信息。 ↩
-
fido2-net-lib contributors, fido2-net-lib。关于面向 .NET 的 FIDO2/WebAuthn 库及其使用示例。 ↩
-
W3C, Secure Contexts — Is origin potentially trustworthy?。关于包括 localhost 和回环地址在内的安全上下文判定。 ↩
-
Microsoft Support, Manage your saved passkeys。关于 Windows 上的本地保存以及同步提供程序的管理。 ↩
-
Microsoft Learn, Support for passkeys in Windows。关于 Windows 对通行密钥的支持,以及与 Windows Hello、TPM 的关系。 ↩
-
Microsoft Learn, Enable Microsoft Entra passkey on Windows。关于保存在 Windows Hello 本地容器中的 Entra 通行密钥。 ↩
-
Microsoft Learn, Enable passkeys (FIDO2) in Microsoft Entra ID与Passkeys (FIDO2) authentication method。关于通行密钥的类型,以及身份验证方法策略与身份验证强度的配置。 ↩
相关文章
共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。
图解 NTLM 与 Kerberos——认证为什么会“回退”到 NTLM
用图解梳理 NTLM 与 Kerberos 的区别。依据官方文档讲解挑战/响应、TGT 与服务票据、SPN 解析不出来时 Negotiate 回退到 NTLM 的条件、中继攻击与 Pass-the-Hash 成立的原因,直至 NTLMv1 被移除。
Windows 安全审核策略与事件日志排查实务——成为看得懂 4625 的信息系统负责人
这是一份用于回应“帮忙查一下登录失败日志”的实务指南。讲解基本审核策略与高级审核策略的关系、至少应启用的子类别、事件 ID 4624/4625/4688 的读法、Security 日志的容量设计,以及用 Get-WinEvent 提取日志的方法。
Windows LAPS 实务指南——告别全部 PC 通用的本地管理员密码
全部 PC 通用的本地管理员密码,是一台失陷就波及全部设备的 Pass-the-Hash 攻击温床。本文讲解已成为 OS 标准功能的 Windows LAPS 如何自动轮换,如何配置保存到 AD/Entra ID,以及运维中的陷阱。
Windows 证书存储实务指南——应该放入用户存储还是计算机存储
客户端证书应该放入用户存储还是计算机存储。从 certmgr.msc 与 certlm.msc 的区别、私钥的权限授予,到用 PowerShell 盘点有效期,系统性地消除证书典型故障的实务指南。
Windows 防火墙与业务应用——入站规则要在安装程序中注册
Windows 业务应用在客户现场无法通信时,如何排查入站规则、监听、网络配置文件与管理策略。讲解不依赖首次启动警告的规则设计、安装程序中的注册与更新,以及防火墙日志的解读方式。
相关主题
与本文相近的主题页面。以本文为起点,可以进一步了解相关服务和其他文章。
Windows 技术主题
汇整 KomuraSoft LLC 关于 Windows 开发、故障调查与既有资产活用文章的主题中心。
常见问题
汇总了咨询这一主题时常见的问题。
- 通行密钥为什么比密码更安全?
- 因为它不把私钥交给登录目标,而是用与本次挑战值和使用目标绑定的签名来完成认证。仅泄露公钥无法伪造签名,也无法从无关的仿冒网站上使用属于真站点的通行密钥。不过,服务器端的正确验证,以及设备、恢复手段和会话的保护仍然必要。
- 指纹或人脸信息会被发送到网站吗?
- WebAuthn 的认证响应不会携带指纹图像或人脸特征值发送给登录目标。生物识别和 PIN 用在用户一侧,用于许可私钥的使用;服务一侧确认的是签名和用户验证的结果。
- 既然不发送私钥,为什么通行密钥还能同步?
- 因为向登录目标的认证和凭据管理器的同步是两条不同的路径。同步型会把私钥加密后复制到各设备之间,但并不是把私钥交给登录目标。同步保管库的解锁与恢复条件因产品和配置而异。
- 手机丢了,使用通行密钥的账户会怎样?
- 同步型在满足保管库恢复条件时,可能可以在另一台设备上继续使用;设备绑定型则需要另外注册的备用凭据或恢复手段。在保护设备、上报丢失的同时确认安全的恢复手段,并把有风险凭据的吊销与既有会话的终止分开执行。如果在服务一侧吊销同一份已同步的凭据,其他设备上的副本也将无法再登录该服务。
- 用了通行密钥就不需要防钓鱼对策了吗?
- 并非如此。通行密钥在防止把凭据交给仿冒域名方面很强,但诱导切换到密码或短信、滥用恢复流程、设备或会话被入侵,都需要另行采取对策。
- 在 Windows Hello 中使用的通行密钥一定是设备绑定型吗?
- 仅凭 Windows Hello 的确认界面无法判断保存位置和是否同步。要把本地容器中的凭据与保存在同步提供程序中的通行密钥区分开,并确认实际的保存位置、设备和组织策略。