Я использую ключ безопасности Yubico с AAGUID ff8a011f3-8c0a-4d15-8006-17111f9edc7d (ключ безопасности от Yubico v5.1) для выполнения проверки подлинности без пароля для моего веб-приложения. Когда я создаю / регистрирую новые учетные данные, я использую атрибут " requireResidentKey = true " в разделе authenticatorSelection параметров создания учетных данных:
...
authenticatorSelection: {
requireResidentKey: true, // note the use of this attribute set to true
userVerification: options.userVerification,
authenticatorAttachment: options.authenticatorAttachment,
},
...
The Данные аттестации , которые возвращаются, содержат идентификационный идентификатор из 16 байтов:
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, похожий на: AUpf0KmNJrRluGG-65D54Q
Затем я сохраняю полученные учетные данные, используя этот 16-байтовый идентификатор в качестве ключа. Когда я использую ключ Yubico для входа, возвращенные данные подтверждения содержат этот же 16-байтовый идентификатор учетных данных:
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)
})
, а затем я могу использовать этот идентификатор учетных данных для извлечения сохраненных данных учетных данных. и подтвердите утверждение. Так что пока все хорошо ...
Я тогда читал черновик W3 C редактора по Веб-аутентификации: API для доступа к Publi c Key Credentials Level 2 и отметил что « requireResidentKey » устарел в пользу атрибута « residentKey », который принимает значение перечисления:
requireResidentKey, типа boolean, defaulting в false Примечание. Этот элемент сохраняется для обратной совместимости с WebAuthn Level 1, но не рекомендуется в пользу residentKey. requireResidentKey игнорируется, если вызывающая сторона предоставляет residentKey, а последняя понимается клиентом. В противном случае используется значение requireResidentKey. Обратите внимание, что значение requireResidentKey по умолчанию равно false.
Если используется в отсутствие residentKey, оно описывает требования проверяющей стороны в отношении учетных данных резидента. Если для requireResidentKey задано значение true, средство проверки подлинности ДОЛЖНО создавать общедоступный клиентский источник учетных данных ключа c при создании открытого ключа доступа c.
residentKey типа ResidentKeyRequirement Примечание. Этот элемент заменяет requireResidentKey . Если оба присутствуют, и клиент понимает residentKey, то используется residentKey, а requireResidentKey игнорируется.
См. ResidentKeyRequirement для описания значений и семантики residentKey.
Поэтому я изменил requireResidentKey до residentKey со значением перечисления " required ", как показано:
authenticatorSelection: {
residentKey: 'required', // now using residentKey attribute
requireResidentKey: true,
userVerification: options.userVerification,
authenticatorAttachment: options.authenticatorAttachment,
},
Теперь, когда я создаю новые учетные данные, я получаю 64 байта Идентификатор удостоверения возвращен. Это было бы хорошо, за исключением того, что когда я использую ключ безопасности Yubico для входа в систему, я получаю возвращенный идентификационный идентификатор 16 байт , который явно не совпадает с 64-байтовым идентификатором, который я сохранил на этапе создания учетных данных.
Интересно, что когда я попытался использовать оба requireResidentKey = true и residentKey = 'required' вместе, я получил свой 16-байтовый идентификационный идентификатор, возвращенный как для подтверждения, так и для подтверждения.
Может ли быть так, что новый атрибут residentKey не поддерживается? Если так, то почему я получил 64-байтовый идентификационный номер? Возможно, это длина нерезидентного идентификатора учетных данных?
Мой код снова работает с использованием старого атрибута requireResidentKey , но я бы хотел знать, что здесь происходит, и если ResidentKey атрибут будет поддерживаться в более новых Yubikeys?