Несоответствие длины идентификатора Yubico / Credential между подтверждением и подтверждением - PullRequest
1 голос
/ 13 марта 2020

Я использую ключ безопасности 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?

...