作者: admin

  • 无用户名登录的 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 的支持及其在实际应用中的普及,无用户名登录有望成为一种常见的身份验证方法。然而,在实施这一特性时,需要注意认证器的存储限制和兼容性问题,以确保用户体验的平滑过渡。

  • CBOR (Concise Binary Object Representation)

    CBOR,全称是简明二进制对象表示(Concise Binary Object Representation),是一种编码方式,常用于物联网(IoT)领域。它的设计目标是提供一种体积更小、更高效的二进制格式,类似于 JSON,但更适合资源受限的环境,如物联网设备。

    CBOR 的特点

    • 紧凑性:CBOR 的编码格式比 JSON 更紧凑,减少了数据传输的体积和存储空间。
    • 高效性:由于其二进制格式,解析和生成 CBOR 数据通常比处理文本格式的 JSON 更高效。
    • 自描述性:CBOR 编码的数据包含类型信息,解析时无需额外的模式(schema)。
    • 广泛支持:大部分编程语言都有相应的 CBOR 编码和解码库,可以方便地处理 CBOR 数据。

    CBOR 与 JSON 的比较

    特性CBORJSON
    格式二进制文本
    数据体积较小较大
    解析效率较高较低
    自描述性
    适用场景物联网、嵌入式系统、网络协议等Web 服务、配置文件等

    示例

    以下是一个简单的 JSON 对象及其对应的 CBOR 编码表示:

    JSON 示例:

    {
      "name": "Alice",
      "age": 30,
      "is_student": false
    }

    CBOR 编码表示:

    A3                                      # map(3)
      64                                    # text(4)
        6E616D65                            # "name"
      65                                    # text(5)
        416C696365                          # "Alice"
      63                                    # text(3)
        616765                              # "age"
      18 1E                                 # unsigned(30)
      6A                                    # text(10)
        69735F73747564656E74                # "is_student"
      F4                                    # false

    CBOR 库

    大部分编程语言都有相应的 CBOR 库,可以方便地进行编码和解码操作。以下是一些常见语言的 CBOR 库:

    • Python: cbor2, cbor
    • JavaScript: cbor
    • Go: github.com/fxamacker/cbor
    • Java: com.fasterxml.jackson.dataformat.cbor
    • C/C++: libcbor

    使用示例

    Python 示例:

    import cbor2
    
    # 编码 JSON 对象为 CBOR
    data = {
        "name": "Alice",
        "age": 30,
        "is_student": False
    }
    encoded = cbor2.dumps(data)
    print(encoded)  # 输出 CBOR 二进制数据
    
    # 解码 CBOR 为 JSON 对象
    decoded = cbor2.loads(encoded)
    print(decoded)  # 输出 {'name': 'Alice', 'age': 30, 'is_student': False}

    结论

    CBOR 提供了一种紧凑、高效的二进制编码格式,适用于资源受限的环境,如物联网设备。通过使用现有的 CBOR 库,可以轻松地在各种编程语言中进行 CBOR 数据的编码和解码操作,在提高数据传输效率的同时,保持了对各种复杂数据结构的支持。

人生梦想 - 关注前沿的计算机技术 acejoy.com 🐾 步子哥の博客 🐾 背多分论坛 🐾 借一步网 沪ICP备2024052574号-1