Featured image of post WebAuthn和密钥:2024年的无密码身份验证Featured image of post WebAuthn和密钥:2024年的无密码身份验证

WebAuthn和密钥:2024年的无密码身份验证

使用WebAuthn和密钥实施无密码身份验证。教程2024年的平台与漫游身份验证器、条件UI和浏览器支持。

几十年来,密码一直是主要的身份验证机制,但它们存在着可查的安全性和可用性问题。WebAuthn(Web 验证)和新兴的密钥生态系统有望用加密安全、防网络钓鱼的身份验证取代密码。到2024年,所有主要平台的密钥支持都已达到关键点,这使得现在实施无密码身份验证的理想时机。

了解 WebAuthn

WebAuthn 是一种 W3C 标准,可在 Web 上启用基于公钥加密的身份验证。核心流程涉及两个操作:注册和认证。在注册期间,服务器向客户端发送加密质询,身份验证器创建新的密钥对,并在服务器上签名存储。在身份验证过程中,服务器发送质询,身份验证者使用私钥进行签名,然后服务器根据存储的密钥验证签名。

Registration:  Server → Challenge → Authenticator (key pair) → Public key → Server
Authentication: Server → Challenge → Authenticator (signs) → Signature → Server (verifies)

私钥永远不会身份验证器设备,这使得WebAuthn从本质上能够抵御网络钓鱼、攻击库和服务器端数据库泄露。


万能钥匙概念

密钥是一种可发现的WebAuthn,它安全地存储在用户的设备上,并通过特定于平台的机制(例如iCloud钥匙串、谷歌密码管理器或微软帐户)在设备之间同步。密钥通过用户可见的帐户管理、跨设备同步、生物识别或PIN验证以及基于QR码的跨设备身份验证扩展了标准WebAuthn。与传统资源不同,密钥旨在由最终直接用户管理。


平台与漫游身份验证器

平台验证器内置于设备中 - Touch ID、Windows Hello 或 Android 生物识别身份验证。漫游身份验证器是通过 USB、NFC 或蓝牙连接的外部安全钥匙,例如 YubiKey 或 Titan Key。它们之间的选择取决于您的安全性和用户体验要求。

特色平台认证器漫游验证器
可用性内置于设备中需要单独购买
便携性仅限于生态系统同步物理便携性
安全优秀(硬件支持)
用户体验无缝(生物识别)需要插件插件
跨设备基于云的同步手动传输

条件用户界面

条件 UI 是一个 WebAuthn 功能,允许浏览器在登录流程中建议自动填充密码。用户可以在自动填充下拉列表中提高 Key 选项以及已保存的密码,从而显着转换率。

const credential = await navigator.credentials.get({
  publicKey: publicKeyCredentialRequestOptions,
  mediation: "conditional",
});

实现需要三个步骤:在凭证获取调用中设置 mediation: "conditional",将 autocomplete="username webauthn" 添加到用户名输入元素,以及正确处理自动填充流程。此功能将密钥身份验证集成到用户已经了解的熟悉的自动填充体验中。


使用 JavaScript 实现

以下代码演示了基本的WebAuthn注册和身份验证流程:

// Registration
const publicKeyCredential = await navigator.credentials.create({
  publicKey: {
    challenge: crypto.getRandomValues(new Uint8Array(32)),
    rp: { name: "My App", id: "example.com" },
    user: {
      id: crypto.getRandomValues(new Uint8Array(16)),
      name: "[email protected]",
      displayName: "User",
    },
    pubKeyCredParams: [{ alg: -7, type: "public-key" }],
    authenticatorSelection: {
      residentKey: "preferred",
      userVerification: "preferred",
    },
  },
});

// Authentication
const assertion = await navigator.credentials.get({
  publicKey: {
    challenge: crypto.getRandomValues(new Uint8Array(32)),
    allowCredentials: credentials.map(cred => ({
      id: base64urlToBytes(cred.id),
      type: "public-key",
    })),
    userVerification: "preferred",
  },
});

服务器端验证需要解析证明对象、验证加密签名并根据依赖方 ID 检查来源。 Node.js 的 @simplewebauthn/server 等库简化了大部分这个过程。


安全考虑

WebAuthn 包括消除所有类别的攻击,网络钓鱼、冲突库、中间和数据库丢失。然而,仍然需要认真执行。始终验证来源是否与依赖方 ID 匹配,生成加密随机一次意愿查询,对身份验证成功尝试实施速度限制,并为设备丢失提供恢复选项。在过渡期间,保留密码后备,同时鼓励用户在密码登录后通过逐步注册来采用密钥。


##结论

密钥代表了十年来网络身份验证安全性方面最显着的改进。随着所有主要平台现在都支持该生态系统,并且用户越来越熟悉生物识别身份验证,2024年将是采用密钥的一年。实施复杂度适中、安全性和用户体验优势显着删除。通过等中密码,您可以消除整个类别的攻击,同时为用户提供更流畅式的身份验证体验。