无用户名登录的 WebAuthn 实现

无用户名登录是一种通过 WebAuthn 进行身份验证的改进方法,其目标是进一步简化用户的登录过程,消除输入用户名的需求。这一特性主要依赖于 Resident Key(驻留密钥)功能,允许认证器在本地存储私钥,从而实现用户身份的无缝识别。下面是这一过程的详细解释:

为什么普通的 WebAuthn 不能实现无用户名登录?

在传统的 WebAuthn 流程中,依赖方(如网站)在验证用户身份时需要提供凭证 ID(Credential ID)给认证器,认证器依赖该凭证 ID 计算出相应的私钥。通常,认证器并不存储私钥,而是通过 Key Warp 等技术加密私钥并将其包含在凭证 ID 中。这意味着认证器可以无限制地生成公私钥对,而无需维护庞大的存储空间。

然而,这也导致了一个问题:在登录时,依赖方必须通过用户名找到对应的凭证 ID,并将其发送给认证器。这就要求用户在验证时必须输入用户名。

Resident Key(驻留密钥)解决方案

Resident Key 功能允许认证器在本地永久存储私钥,从而消除对凭证 ID 的依赖。通过这种方式,认证器可以直接根据依赖方 ID 找到对应的私钥进行身份验证,无需用户输入用户名。

无用户名登录的具体流程

注册时(启用 Resident Key):

  1. 依赖方请求新建凭证
    • 依赖方请求认证器生成一对公私钥,并要求启用 Resident Key。
  2. 认证器生成密钥对
    • 认证器生成一对公私钥,并将私钥存储在永久内存中,与依赖方 ID 和用户 ID 绑定。
  3. 发送公钥给依赖方
    • 认证器将公钥发送给依赖方,依赖方将公钥与用户 ID 绑定并存储。

验证时(无用户名登录):

  1. 依赖方请求验证
    • 依赖方请求验证用户身份,只需提供依赖方 ID。
  2. 用户选择认证器
    • 用户选择用于验证的认证器。
  3. 认证器查找私钥
    • 认证器根据依赖方 ID 查找对应的私钥。如果有多个对应的私钥,认证器会提示用户选择使用哪个身份信息进行登录
  4. 认证器签名挑战
    • 认证器使用找到的私钥签名依赖方发送的挑战(challenge),并将签名结果和用户 ID 返回给依赖方。
  5. 依赖方验证签名
    • 依赖方根据返回的用户 ID 查找对应的公钥,验证签名的正确性。如果签名有效,则允许用户登录。

无用户名登录的示意图

依赖方                  客户端                 认证器
  |-- 验证请求(依赖方 ID) -->|                          |
  |                           |-- 用户选择认证器 ------>|
  |                           |                          |-- 查找私钥
  |                           |                          |-- 签名挑战
  |                           |<-- 返回签名和用户 ID --|
  |<-- 验证签名(公钥验证) --|                          |
  |-- 登录成功(如验证通过) -->|                          |

重要注意事项

  • 存储限制:认证器能永久存储的私钥数量是有限的,因此 Resident Key 功能应仅在真正需要无用户名登录时启用。
  • 兼容性:目前尚无统一的方法检测认证器是否支持 Resident Key 功能,因此在无用户名验证失败时,应回退至常规的 WebAuthn 验证流程,即向用户询问用户名。
  • 安全性:驻留密钥功能要求认证器支持用户身份的安全管理,包括对用户 ID 的安全存储和私钥的安全签名操作。

结论

Resident Key 功能为 WebAuthn 提供了无用户名登录的可能性,进一步简化了用户的登录体验。在未来,随着更多认证器对 Resident Key 的支持及其在实际应用中的普及,无用户名登录有望成为一种常见的身份验证方法。然而,在实施这一特性时,需要注意认证器的存储限制和兼容性问题,以确保用户体验的平滑过渡。

发表评论