Authentication Yubico/凭证ID长度在证明和断言之间不匹配

Authentication Yubico/凭证ID长度在证明和断言之间不匹配,authentication,webauthn,yubico,fido,password-less,Authentication,Webauthn,Yubico,Fido,Password Less,我正在使用AAGUID为ff8a011f3-8c0a-4d15-8006-17111f9edc7d(Yubico v5.1提供的安全密钥)的Yubico安全密钥为我的web应用程序执行无密码身份验证。创建/注册新凭据时,我使用创建凭据选项的Authenticator Selection部分中的属性“requireResidentKey=true: ... authenticatorSelection: { requireResidentKey: true, // note

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

   ...
   authenticatorSelection: {
      requireResidentKey: true, // note the use of this attribute set to true
      userVerification: options.userVerification,
      authenticatorAttachment: options.authenticatorAttachment,
    },
   ...
返回的认证数据包含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编辑关于Web身份验证:访问公钥凭证级别2的API的草稿,并注意到“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字节凭证ID不匹配

有趣的是,当我尝试同时使用requireResidentKey=trueresidentKey='required'时,我得到了为认证和断言返回的16字节凭证ID

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


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

有趣的是,我的非常驻密钥(仅适用于2FA)它们都有64字节的凭证ID,使用预FIDO2 Yubikey和新的Yubikey安全密钥(只有FIDO2一个)。常驻参数有一个16字节的ID。这确实表明,当您同时提供两个参数时,发生了意外情况。实际上有人支持2级吗?MDN文档不包括新的
residentKey
属性。感谢@mackie证实了我的怀疑。因此,我认为新属性还不受支持,因此它使用了
requireResidentKey
的默认值,即
false
。这就解释了为什么我会得到一个64字节的凭证id。有趣的是,我的非常驻密钥(仅适用于2FA)都有64字节的凭证id,使用预FIDO2 Yubikey和新的Yubikey安全密钥(仅适用于FIDO2)。常驻参数有一个16字节的ID。这确实表明,当您同时提供两个参数时,发生了意外情况。实际上有人支持2级吗?MDN文档不包括新的
residentKey
属性。感谢@mackie证实了我的怀疑。因此,我认为新属性还不受支持,因此它使用了
requireResidentKey
的默认值,即
false
。这就解释了为什么我会得到一个64字节的凭证id。