1

我正在使用 AAGUID 为 ff8a011f3-8c0a-4d15-8006-17111f9edc7d(Yubico v5.1 的安全密钥)的 Yubico 安全密钥为我的 Web 应用程序执行无密码身份验证。当我创建/注册新凭据时,我在创建凭据选项的authenticatorSelection部分中使用属性“ requireResidentKey = true ” :

   ...
   authenticatorSelection: {
      requireResidentKey: true, // note the use of this attribute set to true
      userVerification: options.userVerification,
      authenticatorAttachment: options.authenticatorAttachment,
    },
   ...

返回的Attestation 数据包含 16 个字节的凭证 id:

 return navigator.credentials.create({
    publicKey: credentialCreateOptions,
    signal: authAbortSignal,
  }).then(rawAttestation => {
    const attestation = {
      id: rawAttestation.id, // returned 16 byte credential id
      type: rawAttestation.type,
      clientDataJSON: arrayBufferToString(rawAttestation.response.clientDataJSON),
      attestationObject: base64encode(rawAttestation.response.attestationObject),
      extensionData: base64encode(rawAttestation.getClientExtensionResults()),
    }

    return attestation
  }).catch((error) => {
    console.log(error)
    if (error === 'AbortError') {
      throw new Error('the operation was aborted')
    } else {
      throw new Error('the operation was cancelled')
    }
  })

所以例如我会收到一个 16 字节的 base64url id,看起来像:AUpf0KmNJrRluGG-65D54Q

然后我使用这个 16 字节的 id 作为密钥来保存生成的凭证。当我使用 Yubico 密钥登录时,返回的断言数据包含相同的 16 字节凭据 ID:

return navigator.credentials.get({
    publicKey: credentialRequestOptions,
  }).then(rawAssertion => {
    const assertion = {
      id: rawAssertion.id, // same 16 byte credential id as returned from create credential
      type: rawAssertion.type,
      clientDataJSON: arrayBufferToString(rawAssertion.response.clientDataJSON),
      authenticatorData: base64encode(rawAssertion.response.authenticatorData),
      signature: base64encode(rawAssertion.response.signature),
      userHandle: base64encode(rawAssertion.response.userHandle),
    }

    return assertion
  }).catch((error) => {
    throw new Error(error.message)
  })

然后我可以使用这个凭证 ID 来检索我存储的凭证数据并验证断言。所以到目前为止一切都很好......

然后我正在阅读 W3C Editor's Draft on Web Authentication: An API for access Public Key Credentials Level 2并注意到“ requireResidentKey ”已被弃用,取而代之的是采用枚举值的“ residentKey ”属性:

requireResidentKey,布尔类型,默认为 false 注意:保留此成员是为了向后兼容 WebAuthn 级别 1,但不推荐使用 residentKey。如果调用者提供了 residentKey 并且客户端理解了后者,则忽略 requireResidentKey。否则,使用 requireResidentKey 的值。请注意,requireResidentKey 的值默认为 false。

如果在没有 residentKey 的情况下使用,它描述了依赖方对居民凭证的要求。如果 requireResidentKey 设置为 true,则验证者在创建公钥凭证时必须创建客户端驻留的公钥凭证源。

residentKey,类型为 ResidentKeyRequirement 注意:此成员取代 requireResidentKey。如果两者都存在并且客户端理解 residentKey,则使用 residentKey 而忽略 requireResidentKey。

有关 residentKey 的值和语义的描述,请参见 ResidentKeyRequirement。

所以我将requireResidentKey更改为residentKey,其枚举值为“ required ”,如图所示:

    authenticatorSelection: {
      residentKey: 'required', // now using residentKey attribute
      requireResidentKey: true,
      userVerification: options.userVerification,
      authenticatorAttachment: options.authenticatorAttachment,
    },

现在,当我创建一个新凭证时,我会返回一个64 字节的凭证 ID。这本来很好,只是当我使用 Yubico 安全密钥登录时,我得到一个16 字节的凭据 ID,它显然与我在创建凭据阶段保存的 64 字节不匹配。

有趣的是,当我尝试同时使用requireResidentKey = trueresidentKey = 'required'时,我得到了为 Attestation 和 Assertion 返回的 16 字节凭据 ID。

这可能是不支持新的residentKey属性吗?如果是这样,为什么我会得到一个 64 字节的凭证 ID?这可能是非居民凭证 ID 的长度吗?

我的代码正在使用旧的requireResidentKey属性恢复工作,但我很想知道这里发生了什么,以及新的 Yubikeys 是否支持residentKey属性?

4

0 回答 0