FIDO2 与 WebAuthn:无密码认证协议的原理与架构
为什么需要无密码认证
传统密码认证存在结构性缺陷,这些缺陷无法通过更好的密码策略来根本解决:
密码的根本问题:
- 共享秘密模型:密码是用户与服务器之间的"共享秘密"。服务器必须存储密码的某种形式(哈希值),一旦数据库泄露,攻击者可以离线暴力破解。
- 钓鱼脆弱性:密码可以被任何看起来像登录页面的网站收集。用户无法区分合法网站和钓鱼网站。
- 重放攻击:截获的密码可以直接用于再次登录。
- 凭证填充(Credential Stuffing):用户在多个网站重复使用密码,一次泄露导致连锁入侵。
FIDO2 体系概览
FIDO2(Fast IDentity Online 2.0)是由 FIDO Alliance 推动的无密码认证开放标准体系,包含两个核心协议:
| 协议 | 标准组织 | 作用 |
|---|---|---|
| WebAuthn(Web Authentication) | W3C | 定义浏览器与认证器之间的交互 API,是 Web 平台的标准接口 |
| CTAP(Client to Authenticator Protocol) | FIDO Alliance | 定义客户端设备与外部认证器(如安全密钥)之间的通信协议 |
┌─────────────┐ WebAuthn API ┌──────────────┐ CTAP ┌──────────────┐
│ Web 应用 │ ◄──────────────────► │ 平台认证器 │ ◄──────────► │ 外部认证器 │
│ (Relying │ (浏览器实现) │ (Platform │ (USB/NFC/ │ (Roaming │
│ Party) │ │ Authenticator│ BLE) │ Authenticator│
└─────────────┘ └──────────────┘ └──────────────┘核心概念:公钥凭证模型
FIDO2 用公钥密码学替代了密码的共享秘密模型。其核心是凭证(Credential)的概念:
注册(Registration / Ceremony)
当用户首次在某网站注册 FIDO2 认证时:
- 网站生成挑战(Challenge):一个密码学随机数,防止重放攻击。
- 认证器生成密钥对:在认证器内部生成一对非对称密钥(通常为 ECDSA P-256 或 EdDSA Ed25519),私钥永远不离开认证器。
- 认证器创建凭证:将公钥、凭证 ID、用户标识、认证器元数据等打包为认证断言(Attestation),用认证器的证明密钥(Attestation Key)签名后返回给网站。
- 网站存储公钥:网站将凭证 ID 和公钥与用户账户关联存储。网站不存储任何秘密。
注册流程:
网站 (RP) 浏览器 认证器
│ │ │
│ 1. 注册请求 + Challenge │ │
│ ─────────────────────────►│ │
│ │ 2. 调用 authenticator │
│ │ .makeCredential() │
│ │ ────────────────────────►│
│ │ │ 3. 用户验证(UV)
│ │ │ 4. 生成密钥对
│ │ │ 5. 创建 Attestation
│ │ 6. Attestation 对象 │
│ │ ◄────────────────────────│
│ 7. 验证并存储公钥 │ │
│ ◄─────────────────────────│ │认证(Authentication / Assertion)
当用户登录时:
- 网站生成新的 Challenge。
- 认证器使用私钥签名:认证器用注册时生成的私钥对 Challenge + 网站域名(RP ID)+ 其他数据进行签名。
- 网站验证签名:用注册时存储的公钥验证签名。
认证流程:
网站 (RP) 浏览器 认证器
│ │ │
│ 1. 认证请求 + Challenge │ │
│ ─────────────────────────►│ │
│ │ 2. 调用 authenticator │
│ │ .getAssertion() │
│ │ ────────────────────────►│
│ │ │ 3. 用户验证(UV)
│ │ │ 4. 私钥签名
│ │ 5. Assertion 签名 │
│ │ ◄────────────────────────│
│ 6. 用公钥验证签名 │ │
│ ◄─────────────────────────│ │为什么这比密码安全
- 无共享秘密:网站只存储公钥,泄露后攻击者无法冒充用户(没有私钥)。
- 钓鱼免疫:签名数据包含网站域名(RP ID)。钓鱼网站无法获得合法域名的签名,因为认证器会绑定 RP ID。
- 不可重放:每次认证使用新的 Challenge,旧签名无效。
- 私钥不可导出:私钥存储在认证器的安全硬件中,恶意软件无法窃取。
关键安全机制详解
1. 起源绑定(Origin Binding)
WebAuthn 的核心安全特性之一是凭证与来源(Origin)绑定。每个凭证在创建时记录了网站的来源(协议 + 域名 + 端口)。认证时,认证器会验证请求来源是否与凭证绑定的来源一致。
这意味着:
- 在
https://example.com注册的凭证无法在https://evil.com使用 - 即使攻击者诱导用户在钓鱼页面点击"登录",认证器也不会为错误的来源生成有效签名
2. 用户验证(User Verification, UV)
FIDO2 区分两个层次的用户存在性验证:
| 层次 | 缩写 | 含义 | 示例 |
|---|---|---|---|
| 用户存在性 | UP(User Presence) | 确认有人在场 | 触摸安全密钥上的按钮 |
| 用户验证 | UV(User Verification) | 确认是特定用户 | 指纹、PIN 码、面部识别 |
- UP 是最基本要求,防止远程无人操作。通常通过物理触摸实现。
- UV 是更强的验证,确认操作者的生物特征或知识因子。
userVerification 参数:
"required":必须进行 UV"preferred":优先 UV,但不强制"discouraged":仅 UP,不需要 UV
3. 认证器类型
平台认证器(Platform Authenticator):
- 集成在用户设备中(如 Windows Hello、Apple Touch ID/Face ID、Android 指纹)
- 私钥存储在设备的安全硬件中(如 TPM、Secure Enclave、TEE)
- 通常支持用户验证(生物识别或设备 PIN)
- 独立硬件设备(如 YubiKey、Feitian 安全密钥)
- 通过 USB、NFC 或 BLE 与设备通信
- 使用 CTAP 协议与平台交互
- 通常仅支持用户存在性(触摸),部分型号支持 PIN
4. 证明(Attestation)
注册时,认证器可以提供证明声明(Attestation Statement),向网站证明认证器的真实性和类型:
- 基本证明(Basic Attestation):认证器用制造商的证明密钥签名,网站可以验证认证器是否为正品。
- 匿名证明(Anonymization CA / AnonCA):通过中间 CA 隐藏具体设备型号,防止跨站点追踪。
- 无证明(None Attestation):不提供证明,适用于隐私敏感场景。
- 自证明(Self Attestation):认证器用自己的密钥签名,仅证明密钥来自同一认证器。
5. 签名计数器(Signature Counter)**
认证器维护一个签名计数器,每次签名操作递增。网站可以通过比较计数器值来检测认证器是否被克隆:
- 如果新认证的计数器值 ≤ 上次记录的值,说明可能有一个克隆的认证器在使用
- 平台认证器可能不支持计数器(计数器值为 0),但漫游认证器通常支持
WebAuthn API 核心对象
PublicKeyCredential 类型
WebAuthn 的核心是 PublicKeyCredential 对象,包含:
- rawId:凭证的唯一标识符(ArrayBuffer)
- response:
AuthenticatorAttestationResponse(注册时):包含 attestationObject 和 clientDataJSON
- AuthenticatorAssertionResponse(认证时):包含 authenticatorData、signature、userHandle
- authenticatorAttachment:
"platform"或"cross-platform" - clientExtensionResults:客户端扩展结果
authenticatorData 结构
认证器数据是认证器生成的二进制数据,包含:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│ RP ID Hash (32 bytes) │
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│ Flags │ Sign Count (4 bytes) │
├─────────┴─────────────────────────────────────────────────────────┤
│ Attested Credential Data (variable) │
├───────────────────────────────────────────────────────────────────┤
│ Extensions (variable) │
└───────────────────────────────────────────────────────────────────┘Flags 字段:
- Bit 0 (
UP):用户存在性标志 - Bit 2 (
UV):用户验证标志 - Bit 6 (
AT):认证数据中包含已证明凭证数据 - Bit 7 (
ED):认证数据中包含扩展数据
Passkey:FIDO2 的用户体验进化
Passkey 是 FIDO Alliance 于 2022 年提出的品牌术语,指可同步的 FIDO2 凭证。它解决了传统 FIDO2 的一个关键可用性问题:凭证绑定到单一设备。
Passkey 的核心特性
- 跨平台同步:Passkey 可以通过平台云服务(如 Apple iCloud Keychain、Google Password Manager、Microsoft Account)在用户的多台设备间同步。
- 设备间认证(Cross-Device Authentication):通过 CTAP 2.2 的
authenticatorGetAssertion配合 QR 码或蓝牙,用户可以用手机为桌面浏览器登录提供认证。 - 无感知发现(Discoverable Credentials / Resident Keys):Passkey 是可发现凭证,用户无需先输入用户名,浏览器会自动列出该网站的可用 Passkey。
Passkey 与传统 FIDO2 安全密钥的区别
| 特性 | 传统 FIDO2 安全密钥 | Passkey |
|---|---|---|
| 凭证存储 | 绑定单一设备 | 可跨设备同步 |
| 备份 | 无(丢失即失效) | 通过云同步恢复 |
| 用户体验 | 需要物理设备 | 集成在常用设备中 |
| 安全模型 | 硬件隔离 | 依赖平台安全(TEE/SE + 云加密) |
| 互操作性 | 高(标准硬件) | 依赖平台生态 |
安全模型分析
FIDO2 能防御的攻击
| 攻击类型 | 防御机制 |
|---|---|
| 钓鱼攻击 | 来源绑定(Origin Binding) |
| 数据库泄露 | 网站不存储秘密,仅存储公钥 |
| 重放攻击 | 每次认证使用唯一 Challenge |
| 中间人攻击 | Challenge-Response + TLS |
| 凭证填充 | 每个网站使用不同密钥对 |
| 恶意软件窃取密钥 | 私钥在硬件安全模块中,不可导出 |
FIDO2 的局限与注意事项
- 设备丢失风险:如果用户的唯一认证器丢失且没有备份,将无法登录。Passkey 的同步机制缓解了这个问题。
- 首次注册信任:注册时网站需要信任认证器的证明(Attestation)。如果证明验证不严格,攻击者可能注册伪造的认证器。
- 平台依赖:Passkey 的安全性依赖于平台(操作系统、云服务)的安全性。如果平台账户被入侵,同步的 Passkey 可能暴露。
- 降级攻击:如果网站同时支持密码和 FIDO2,攻击者可能诱导用户使用较弱的密码认证。最佳实践是完全移除密码。
- CTAP 传输层安全:USB/NFC/BLE 传输本身不提供加密,依赖上层协议(WebAuthn 的 Challenge-Response)保证安全。
与现有认证体系的关系
FIDO2 与 PKI
FIDO2 和 PKI(公钥基础设施)都基于公钥密码学,但设计目标不同:
| 维度 | PKI / X.509 | FIDO2 / WebAuthn |
|---|---|---|
| 信任模型 | 层次化 CA 信任链 | 直接信任(网站直接验证认证器) |
| 证书管理 | 需要证书颁发、续期、吊销 | 无证书管理开销 |
| 身份绑定 | 证书绑定到身份(需要身份验证) | 凭证绑定到网站(RP ID) |
| 用户验证 | 依赖证书中的身份信息 | 由认证器本地完成 |
| 互操作性 | 全球通用 | 需要网站和浏览器支持 |
FIDO2 与 OIDC/SAML
FIDO2 通常与 OIDC(OpenID Connect)或 SAML 结合使用:
- FIDO2 作为认证因子(替代密码)
- OIDC/SAML 作为联邦身份协议(传递认证结果和用户属性)
标准化现状
- WebAuthn Level 1:2019 年 3 月成为 W3C 推荐标准
- WebAuthn Level 2:2021 年 4 月成为 W3C 推荐标准
- WebAuthn Level 3:W3C 正在开发中(2024-2025 年)
- CTAP 2.0:FIDO Alliance 规范
- CTAP 2.1:增加了设备间认证等功能
- CTAP 2.2:最新版本,持续更新中
总结
FIDO2/WebAuthn 代表了身份认证从"你知道什么"(密码)向"你拥有什么"(认证器)和"你是什么"(生物识别)的根本性转变。其核心安全优势来源于:
- 公钥密码学替代共享秘密
- 来源绑定实现钓鱼免疫
- 硬件隔离保护私钥
- 挑战-响应防止重放攻击