WebAuthn 基础

共 17 题
📑 题目列表 17 题
#
★★★

1. AuthenticatorAttestationResponse/AssertionResponse/CBOR/COSE 在协议层的工程价值

请解释 WebAuthn 中的 AuthenticatorAttestationResponse、AuthenticatorAssertionResponse、CBOR 与 COSE 四种数据结构在协议层的工程价值,以及它们各自承担什么角色?

  • 两种 Response 对象(attestation/assertion)的字段与差异
  • CBOR 二进制编码在协议中的用途
  • COSE 密钥格式与公钥/签名描述的工程价值

AuthenticatorAttestationResponse 是注册(navigator.credentials.create)返回的结果,包含 clientDataJSON、attestationObject;AuthenticatorAssertionResponse 是断言(navigator.credentials.get)返回的结果,包含 clientDataJSON、authenticatorData、signature、userHandle。CBOR(Concise Binary Object Representation)是紧凑的二进制编码格式,用于序列化 attestationObject 与 authenticatorData 中的扩展字段,比 JSON 更节省空间。COSE(CBOR Object Signing and Encryption)则是基于 CBOR 的密钥/签名描述格式,用于表达公钥算法与参数(如 EC2/RSA 曲线与密钥)。工程上,前端负责采集这些原始字节,后端用库(如 @simplewebauthn/server)解析 CBOR、还原 COSE 公钥并验证签名。

理解这些协议层结构,才能明白"前端拿到的是二进制 blob,不能直接当 JSON 用",也解释了为什么服务端必须用支持 CBOR/COSE 的解析库。这是 WebAuthn 工程落地的基础,也是区分"会调 API"与"理解协议"的分水岭。

// 注册时采集的原始响应
const cred = await navigator.credentials.create({ publicKey });
// cred.response 是 AuthenticatorAttestationResponse
console.log(cred.response.clientDataJSON, cred.response.attestationObject);
// 登录时采集的原始响应
const asserted = await navigator.credentials.get({ publicKey });
// asserted.response 是 AuthenticatorAssertionResponse
console.log(asserted.response.signature, asserted.response.authenticatorData);
#
★★★

2. WebAuthn(navigator.credentials.create/get)

请介绍 WebAuthn 的核心 API navigator.credentials.create 与 navigator.credentials.get 的用途、参数与典型调用流程?

  • create 与 get 各自用途(注册/登录)
  • publicKey 参数结构(challenge、rp、user、pubKeyCredParams)
  • 与 Credential Management API 的关系

WebAuthn 通过 navigator.credentials.create() 完成注册(创建新的公钥凭证),通过 navigator.credentials.get() 完成登录/断言(使用已有凭证)。两者都接收一个 publicKey 选项对象。create 需要 rp(依赖方)、user(含 id、name、displayName)、challenge、pubKeyCredParams(可接受的算法,如 ES256)等;get 需要 challenge、allowCredentials(可选凭证列表)。它们建立在 Credential Management API 之上,返回的 Promise 在用户完成认证器交互后 resolve 为 PublicKeyCredential。注意 create/get 必须在安全上下文(HTTPS 或 localhost)下才可用。

这是 WebAuthn 最核心的两个入口,理解其参数结构(尤其 challenge 必须由服务端生成且随机)是任何实现的基础。面试考察 API 的完整性与对参数语义的理解。

const publicKey = {
  challenge: new Uint8Array(/* 服务端下发的随机 challenge */),
  rp: { id: "example.com", name: "Example" },
  user: { id: new Uint8Array(16), name: "user@ex.com", displayName: "User" },
  pubKeyCredParams: [{ type: "public-key", alg: -7 }], // ES256
  timeout: 60000,
};
const credential = await navigator.credentials.create({ publicKey });
#
★★★

3. 平台认证器(指纹、Face ID、Windows Hello)

什么是平台认证器(Platform Authenticator)?它在指纹、Face ID、Windows Hello 等场景下如何工作,与跨平台认证器有何区别?

  • 平台认证器与跨平台认证器的定义
  • 生物识别(指纹、Face ID、Windows Hello)的实现机制
  • authenticatorAttachment 属性

平台认证器(Platform Authenticator)是内置于设备/操作系统中的认证器,绑定了特定设备,如笔记本电脑的 Windows Hello、iPhone/iPad 的 Touch ID/Face ID、Android 的指纹。它通过 secure enclave 或 TPM 等安全硬件存储私钥,并在本地用生物识别完成 userVerification(UV)。与之相对的是跨平台认证器(Cross-Platform Authenticator),如 USB 安全密钥或一部手机,可随设备移动。通过 credential.authenticatorAttachment 可判断平台认证器("platform")还是跨平台认证器("cross-platform")。平台认证器通常更便捷(无需额外硬件),但旧实现可能不跨设备同步。

平台认证器是"无密码"体验的核心载体,把生物识别与强密钥绑定。理解其本地 UV 与安全硬件的依赖,有助于设计注册流程中平台认证器的优先级与用户体验。

#
★★★

4. WebAuthn 标准与 FIDO2 的关系

请说明 WebAuthn 标准与 FIDO2 之间的关系,以及它们各自定义了什么?

  • WebAuthn 与 FIDO2 的隶属关系
  • CTAP 的位置
  • 生态中各标准的角色

WebAuthn 是 W3C 发布的 Web 标准,定义浏览器内的 Web 认证 API;FIDO2 是 FIDO Alliance 推动的一套规范,由 WebAuthn(浏览器↔RP)与 CTAP(认证器↔浏览器/客户端)两部分组成。简单说,FIDO2 是"无密码认证"的整体方案,WebAuthn 是其中面向 Web 前端的部分,而 CTAP 负责浏览器与认证器(如 USB 安全密钥)之间的传输。因此"WebAuthn 是 FIDO2 的 Web 前端实现"这一说法最准确,两者常被混用但在技术上层级不同。

面试经常把 WebAuthn 与 FIDO2 混提,清楚二者"Web 标准 vs 整体框架"的关系,并点出 CTAP 这一层,能体现对 FIDO 生态的全局理解。

#
★★

5. WebAuthn 的认证流程,注册与断言的挑战-响应?

请描述 WebAuthn 中注册与断言(登录)两个流程各自如何实现"挑战-响应"(challenge-response)机制?

  • 注册流程的挑战-响应
  • 断言流程的挑战-响应
  • challenge 的服务端存续

注册流程:服务端生成随机 challenge 下发,前端 navigator.credentials.create 让认证器对 challenge 签名并返回 attestation(含公钥),服务端验证签名后保存公钥。断言流程:服务端再次生成随机 challenge,前端 navigator.credentials.get 让认证器用对应私钥对 challenge 签名,返回 assertion(clientDataJSON + authenticatorData + signature),服务端用已保存公钥验签并核对 challenge 与 origin。两者的核心都是"服务端出题、认证器用私钥签名回答",且 challenge 必须一次性、随机、有服务端会话绑定,防止重放攻击。

挑战-响应是无密码认证的信任基础:私钥永不出设备,服务端只验证签名。理解"challenge 随请求下发且服务端校验"是防止重放的核心,也是面试的必考点。

#
★★

6. navigator.credentials.create() 的 authenticatorSelection(residentKey、userVerification、authenticatorAttachment)在注册流程的配置与用户体验影响?

在注册流程中,navigator.credentials.create() 的 authenticatorSelection 里 residentKey、userVerification、authenticatorAttachment 三个选项如何配置?它们分别对用户体验有什么影响?

  • authenticatorSelection 的三个字段语义
  • residentKey(required/preferred/discouraged)
  • userVerification 与 authenticatorAttachment 的取舍

authenticatorSelection 控制注册时对认证器的要求。residentKey 决定是否创建可发现凭证(discoverable credential):required 强制预留即可发现(利于无输用户名登录),preferred 有则用之、无则退回,discouraged 不创建。userVerification 控制是否要求用户验证(指纹/Face ID/PIN):required 强制验证,preferred 允许回退,discouraged 尽量不验证。authenticatorAttachment 可限定 platform 或 cross-platform。工程上通常用 preferred 平衡安全与兼容——required 会减少可用认证器数量、降低转化率,而平台认证器(platform)配合 residentKey 能提供最流畅的无密码体验。

这三个字段是配置"安全 vs 兼容"的旋钮。配置过严会排除大量认证器(如不支持 residentKey 的旧设备),过松则安全性不足。回答时点出"required 最安全但最容易失败、preferred 是折中"是加分项。

const publicKey = {
  challenge, rp, user, pubKeyCredParams,
  authenticatorSelection: {
    residentKey: "preferred",
    userVerification: "preferred",
    authenticatorAttachment: "platform",
  },
};
#
★★

7. CTAP 2.2 在现代前端项目的工程价值

CTAP 2.2 相对于 CTAP 2.1 引入了哪些能力?它在现代前端项目中有什么工程价值?

  • CTAP 2.2 的新特性(hmacSecret、largeBlob、minPinLength 等)
  • 对前端 WebAuthn 应用的间接影响
  • 与浏览器 WebAuthn 的配合

CTAP 2.2 是 FIDO2 认证器协议的最新版本,新增并完善了多项能力,如 largeBlob(在认证器上存储大块数据)、hmac-secret(HMAC 密钥派生)、minPinLength(查询最小 PIN 长度)、bioEnrollment(生物识别管理)等。虽然 CTAP 是浏览器与认证器之间的传输协议,前端不直接调用,但浏览器通过 WebAuthn extensions 暴露其中一部分能力,因此 CTAP 2.2 的普及让前端能使用更丰富、更安全的认证器能力。工程价值在于:它是"浏览器 WebAuthn → 认证器"能力链路的底层支撑,前端可通过扩展协商这些能力,从而提升安全性与用户体验。

前端开发者通常不直接接触 CTAP,但理解它决定了"哪些 WebAuthn extension 可用"以及"认证器的能力边界"。回答时强调 CTAP 与 WebAuthn extensions 的对接关系,能体现对底层协议的理解。

#
★★

8. FIDO2 的 Attestation 在凭证验证的工程价值

FIDO2 的 Attestation(认证器证明)在凭证验证中有什么工程价值?为什么很多服务端选择忽略或验证它?

  • Attestation 的概念与用途
  • attestation 的格式(none、packed、tpm、android-key 等)
  • 验证 or 忽略的工程取舍

Attestation 是认证器在注册时提供的"证明",用于向 RP 证明凭证确实由某个受信任的认证器生成(如硬件安全密钥或特定 TPM),并携带认证器信息。它能让服务端建立"信任链"——例如仅允许特定厂商的高安全认证器,或用于风控/合规审计。Attestation 有不同格式(none、packed、tpm、android-key、apple 等),需要通过对应 CA 证书链验证。但很多网站(尤其消费级)选择忽略 attestation(attestation: "none"),因为:验证需要维护 CA 证书信任库、成本高,且可能涉及隐私(attestation 可追踪认证器)。折中方案是使用 Anonymization CA(如 Apple/Google 的隐私 CA)或用 attestation 做统计而不做准入。

理解"attestation 是可选的安全增强"而非必需,是工程务实的关键。回答点出"信任企业级硬件的场景要验证,消费级场景常忽略以降低成本与隐私风险"是成熟做法。

#
★★

9. Passkeys 跨设备同步(iCloud Keychain、Google Password Manager)

Passkeys 是如何实现跨设备同步的?iCloud Keychain 与 Google Password Manager 的同步机制有什么异同?

  • Passkey 同步的原理
  • 跨设备同步的厂商实现
  • 同步与安全(端到端加密)的关系

Passkeys 是"可同步的 WebAuthn 凭证",跨设备同步由平台(操作系统/密码管理器)负责。Apple 通过 iCloud Keychain 在 Apple 设备间同步 passkey,Google 通过 Google Password Manager 同步到 Android 与 Chrome(含跨平台扩展)。同步的私钥通常用端到端加密保护,并绑定用户账户(如 Apple ID / Google 账号)与设备解锁。实现上,同步 passkey 通常对应"可发现凭证 + 平台认证器",凭证以"被同一账号体系下其他设备可用的形式"存在。由于私钥能跨设备迁移,同步 passkey 的防钓鱼与便利性兼顾,但把信任放在了平台厂商的同步服务上。

Passkey 的核心价值就是"跨设备",这依赖平台同步。理解同步的端到端加密与账户绑定,以及其与"不可导出的硬件密钥"(如 YubiKey)的差异,是回答这类问题的关键。

#
★★

10. largeBlob 与 transactionPayments extensions 的工程价值

WebAuthn 的 largeBlob 与 transactionPayments 两个扩展各有什么工程价值?它们分别在什么场景下使用?

  • largeBlob 扩展的用途
  • transactionPayments 扩展的用途
  • 前端如何使用这些扩展

largeBlob 扩展允许在认证器上存储一块较大的数据(如不超过几百字节到 KB 级),供 RP 随断言读写,常用于离线/无服务器场景存储用户数据或轻量属性,避免依赖服务端回传。transactionPayments 扩展用于在认证器上展示并确认"交易上下文"(如付款金额、收款方),使用户在认证器屏上确认交易内容,防止恶意网页篡改交易信息,适用于在线支付等高安全场景。前端通过 WebAuthn 的 extensions 字段传入并在回复中读取扩展结果,但能否使用取决于认证器与浏览器支持情况。

这两个扩展展示 WebAuthn 的"可扩展性":面向特定场景(离线数据存储与交易确认)。这要求前端在调用时探测扩展支持并优雅降级,是理解"WebAuthn 不只是登录"的良好切入。

#
★★

11. Backup Eligibility 与 State 在多设备的工程价值

WebAuthn 的 Backup Eligibility 与 Backup State 是什么?它们在多设备场景下有什么工程价值?

  • Backup Eligibility 与 Backup State 的含义
  • 两者在 authenticatorData 中的表示
  • 对多设备凭证管理的意义

Backup Eligibility 表示"该凭证是否具备被同步备份的能力"(即是否可被同步到其他设备),Backup State 表示"该凭证当前是否已被备份"。两者由认证器在创建时报告,并记录在 authenticatorData 的 flags 中(如 BE 位与 BS 位)。工程价值:RP 可据此判断凭证是否属于"可同步 passkey"还是"仅本设备"凭证,从而决定安全策略(如敏感操作要求 BE=0 的硬件密钥),或用于 UI 展示(告诉用户凭证是否随账号同步)。在多设备场景,这帮助管理"设备无关的 passkey"与"设备绑定的凭证"的差异。

这是 WebAuthn 处理"同步 vs 本地"凭证的关键信号。理解 BS/BE 位能帮助后端区分 passkey 类型、制定不同安全等级,也是"多设备凭证管理"的工程基础。

#

12. Authenticator Attachment(platform/cross-platform)的工程价值

什么是 Authenticator Attachment?platform 与 cross-platform 两种类型的工程价值和对 UX 的影响是什么?

  • authenticatorAttachment 两种取值
  • 对 UI 与流程的影响
  • 如何利用它做策略决策

authenticatorAttachment 标识认证器是 platform(平台内建,如 Face ID、Windows Hello)还是 cross-platform(跨平台,如 USB 安全密钥、手机)。工程价值:前端在注册时可据此判断应采用哪种 UI 与说明(如提示"使用本机指纹" vs "插入安全密钥");登录时可用 allowCredentials 过滤可用的 cross-platform 凭证以缩小认证器交互范围;后端可基于 attachment 施安全策略(如高权限操作要求 cross-platform 硬件密钥)。对 UX 而言,platform 认证器更快捷、少一步硬件操作,cross-platform 则便携可跨设备。

attachment 是"方案匹配设备能力"的输入,也是区分"便捷"与"硬件级安全"的实用维度。回答时结合 UI 分支与策略分层,能体现工程落地思考。

#

13. CTAP 2.2 CDA 跨设备认证的现状

什么是 CTAP 2.2 的 CDA(跨设备认证)?其当前实现现状如何?

  • CDA 的概念
  • 与 Hybrid transport 的关系
  • 当前浏览器/生态支持现状

CDA(Cross-Device Authentication)是 CTAP 2.2 引入的跨设备认证机制,用于在没有本地认证器的设备上,通过另一台设备(如手机)完成认证,通常通过 Hybrid transport(如 QR 码 + BLE/局域网)传输。它让"手机上的 passkey 在电脑上登录"成为可能。现状:CDA 已在 Chrome/Edge 等主流浏览器中通过 Hybrid 流程实现,但标准化仍处于推进中,Safari/Firefox 等对该特性的支持与体验仍不一致,且依赖蓝牙/局域网等传输的可用性。工程上通常用 QR 码发起、在手机端完成生物识别后回传签名。

CDA 是"跨设备登录"的底层机制,理解其与 Hybrid transport 的关系与浏览器支持差异,能帮前端做好跨设备登录的 feature detection 与回退。

#

14. Passkey 与平台认证器,跨设备同步的实现?

Passkey 与平台认证器如何实现跨设备同步?平台认证器本应是"设备绑定"的,为什么能跨设备?

  • 平台认证器与 passkey 的关系
  • 同步的机制(端到端加密、账户绑定)
  • 同步对安全模型的影响

传统平台认证器把私钥绑定在单一设备(secure enclave),但 Passkey 出现后,平台认证器与"可同步凭证"结合,私钥可随平台的账户体系(Apple ID、Google 账号)同步到其他设备。同步时,私钥以端到端加密形式存储在平台云服务,新设备解锁后用对应密钥派生或恢复私钥副本。因此"平台认证器跨设备"其实依赖"平台同步服务 + 端到端加密 + 账户登录",而非私钥本身可移动。这意味着信任从"单个设备"转移到"平台账户体系",带来了便利但也让安全边界扩大。

这是 Passkey 与"传统硬件密钥不导出"之间最关键的差异。回答时点明"同步由平台账户体系承载、私钥端到端加密",并讨论便利与信任模型的权衡,是加分项。

#

15. WebAuthn 的安全属性,防钓鱼与防重放?

WebAuthn 如何实现防钓鱼(anti-phishing)与防重放(anti-replay)?其安全属性来自哪里?

  • 防钓鱼的机制(origin 绑定、rpIdHash)
  • 防重放的机制(随机 challenge、计数器)
  • 安全属性的来源

防钓鱼:WebAuthn 绑定 RP ID(rpIdHash)与 origin,签名内容包括 clientDataJSON 里的 origin 与 challenge,认证器回复的 authenticatorData 含 rpIdHash。即使攻击者伪造与真实站点外观相同的页面,其 origin 不同,签名验证会失败,从而无法用窃取的凭证。防重放:每次认证使用服务端新生成的随机 challenge(一次性),且过期即失效,authenticatorData 中还有签名计数器(signCount),服务端检测计数器异常则判定重放。这些安全属性来自"私钥私密 + 签名绑定在 origin/challenge 上",而非依赖用户肉眼辨别钓鱼页。

防钓鱼与防重放是 WebAuthn 相对密码的核心优势。回答时把"origin/rpId 绑定"与"一次性 challenge + 计数器"两条线讲清,能体现对安全模型的理解。

#

16. WebAuthn 与 MFA,作为第二因素的集成?

WebAuthn 如何作为第二因素(MFA)集成到现有认证流程中?前端如何设计?

  • 作为 MFA 第二因素的集成方式
  • 与密码/SSO 的组合
  • 前端流程设计

WebAuthn 可作为第二因素,在"账号+密码"或"账号+短信"之后增加"密钥/生物识别"验证。这通常对应"先密码后 WebAuthn"的两步流程:第一步校验密码,第二步调用 navigator.credentials.get 做断言,用 allowCredentials 限定该用户已注册的凭证。也可结合 SSO,在 IdP 侧完成 WebAuthn 以增强整个会话。前端设计中,需在密码成功后跳转/展示 WebAuthn 步骤,处理认证器选择、超时、重试与降级(如回退 TOTP/短信)。这是"无密码目标"与"渐进迁移"之间的过渡策略。

把 WebAuthn 作为第二因素是很多企业的务实路径,既有强安全又能渐进迁移。回答时区分"主因素"与"第二因素"两种用法的流程差异,并强调降级路径,是工程成熟度的体现。

#

17. WebAuthn 的 userHandle(user.id)与多账号,同一 RP 下多凭证的区分、user.displayName 更新与账号迁移的边界?

WebAuthn 的 userHandle(user.id)在多账号场景下如何区分同一 RP 下的多个凭证?user.displayName 更新与账号迁移的边界如何处理?

  • userHandle 的语义与作用
  • 同一 RP 下多凭证的区分方式
  • displayName 更新与账号迁移的边界

userHandle 是创建凭证时赋给用户的内部标识(user.id),服务端用它把凭证关联到具体账号。同一 RP 下多个凭证用 userHandle 可以区分不同用户;登录(可发现凭证)时,断言响应里的 userHandle 可让服务端识别"这次是哪个账号",用于无用户名登录。user.displayName 是展示名,可更新而不影响凭证(它不是凭证标识)。账号迁移的边界:WebAuthn 凭证严格绑定 RP 与 userHandle,若用户账号体系变更(如 userHandle 改变),原凭证失效,需重新注册;迁移时应保留稳定的 userHandle 或以新身份重新绑定,并在服务端维护 userHandle↔账号映射以平滑迁移。

多账号与迁移是产品化 WebAuthn 绕不开的坑。理解 userHandle 是"凭证↔账号"的关联键、displayName 只是展示层,以及迁移时需重新注册或保持 userHandle 稳定,能体现工程经验。