背景与价值无密码登录提升安全与体验,杜绝密码泄露与钓鱼风险。Passkeys 跨设备同步(平台密码管理器)使登录更顺滑,降低支持成本。注册流程(前端)async function startRegistration() { // 从后端获取创建参数(含挑战challenge、RP、用户信息与算法) const options = await (await fetch('/webauthn/register/options')).json(); options.challenge = base64urlToBuffer(options.challenge); options.user.id = base64urlToBuffer(options.user.id); const cred = await navigator.credentials.create({ publicKey: options }); const attestation = serializeCredential(cred as PublicKeyCredential); const res = await fetch('/webauthn/register/verify', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(attestation) }); return res.ok; } function serializeCredential(cred: PublicKeyCredential) { const resp = cred.response as AuthenticatorAttestationResponse; return { id: cred.id, rawId: bufferToBase64url(cred.rawId), type: cred.type, response: { clientDataJSON: bufferToBase64url(resp.clientDataJSON), attestationObject: bufferToBase64url(resp.attestationObject) } }; } function base64urlToBuffer(str: string) { const pad = (4 - (str.length % 4)) % 4; const s = (str + '='.repeat(pad)).replace(/-/g, '+').replace(/_/g, '/'); const bin = atob(s); const buf = new ArrayBuffer(bin.length); const view = new Uint8Array(buf); for (let i = 0; i < bin.length; i++) view[i] = bin.charCodeAt(i); return buf; } function bufferToBase64url(buf: ArrayBuffer) { const bytes = new Uint8Array(buf); let bin = ''; for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]); return btoa(bin).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, ''); } 登录流程(前端)async function startLogin() { const options = await (await fetch('/webauthn/login/options')).json(); options.challenge = base64urlToBuffer(options.challenge); options.allowCredentials = options.allowCredentials.map((c: any) => ({ ...c, id: base64urlToBuffer(c.id) })); const assertion = await navigator.credentials.get({ publicKey: options }); const data = serializeAssertion(assertion as PublicKeyCredential); const res = await fetch('/webauthn/login/verify', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(data) }); return res.ok; } function serializeAssertion(cred: PublicKeyCredential) { const resp = cred.response as AuthenticatorAssertionResponse; return { id: cred.id, rawId: bufferToBase64url(cred.rawId), type: cred.type, response: { clientDataJSON: bufferToBase64url(resp.clientDataJSON), authenticatorData: bufferToBase64url(resp.authenticatorData), signature: bufferToBase64url(resp.signature), userHandle: resp.userHandle ? bufferToBase64url(resp.userHandle) : null } }; } 后端要点(概念与校验)注册校验:验证 `clientDataJSON.challenge`、`origin` 与 `type`,解析 `attestationObject` 提取公钥;存储凭证 ID 与公钥。登录校验:验证挑战、`origin`、计数器与签名;计数器递增防重放;返回会话标识。设计与兼容平台凭证(Passkeys)优先;跨设备同步降低重复注册。回退策略:不支持设备提供密码或一次性验证码;支持“发现凭证”登录减少用户搜索凭证的负担。可用性提示:明确引导使用系统密码管理器;支持安全密钥(USB/NFC/BLE)。安全治理限制注册来源(域名、RP ID)、启用 HTTPS 与强 CSP;记录失败原因以优化提示。保护隐私:不在日志中记录原始凭证/公钥,仅存储必要元数据。指标验证(Chrome 128/Edge 130/iOS 17+)注册成功率:≥ 96%。登录成功率:≥ 98%。交互耗时(P95):注册 ≤ 6s;登录 ≤ 2.2s。失败原因分布:设备不支持/用户取消占比 ≥ 80% 的失败样本。测试清单不同平台(桌面/移动/安全密钥)的注册与登录路径均成功或合理回退。计数器与签名校验正确;挑战唯一且时效性控制合理。跨设备同步:Passkeys 登录稳定,凭证发现路径无异常。应用场景账户登录、支付确认、企业内网强身份校验、开发者/管理员高安全入口。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
1.613770s