我正在使用 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 = true和residentKey = 'required'时,我得到了为 Attestation 和 Assertion 返回的 16 字节凭据 ID。
这可能是不支持新的residentKey属性吗?如果是这样,为什么我会得到一个 64 字节的凭证 ID?这可能是非居民凭证 ID 的长度吗?
我的代码正在使用旧的requireResidentKey属性恢复工作,但我很想知道这里发生了什么,以及新的 Yubikeys 是否支持residentKey属性?