Yubikey 5 NFC: получите "упакованный" аттестат
Со следующим запросом JavaScript:
navigator.credentials.create({
publicKey: {
// random, cryptographically secure, at least 16 bytes
challenge: new Uint8Array(16),
// relying party
rp: {
id: 'localhost',
name: 'My website'
},
user: {
id: new Uint8Array(16),
name: 'Tang',
displayName: 'Tang'
},
pubKeyCredParams: [
{
type: "public-key", alg: -7
}
],
attestation: "direct"
}
})
совместимый с FIDO2 NFC Yubikey 5 систематически возвращает "fido-u2f"
акт аттестации:
%{
"attStmt" => %{
"sig" => <<48, 69, 2, 33, 0, 132, 31, 225, 91, 58, 61, 190, 47, 66, 168, 8,
177, 18, 136, 106, 100, 219, 54, 52, 255, 103, 106, 156, 230, 141, 240,
82, 130, 167, 204, 128, 100, 2, 32, 61, 159, 126, 9, 244, 55, 100, 123,
169, ...>>,
"x5c" => [
<<48, 130, 2, 188, 48, 130, 1, 164, 160, 3, 2, 1, 2, 2, 4, 3, 173, 240,
18, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 46, 49,
44, 48, 42, 6, 3, 85, 4, 3, 19, ...>>
]
},
"authData" => <<73, 150, 13, 229, 136, 14, 140, 104, 116, 52, 23, 15, 100,
118, 96, 91, 143, 228, 174, 185, 162, 134, 50, 199, 153, 92, 243, 186, 131,
29, 151, 99, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...>>,
"fmt" => "fido-u2f"
}
Как получить FIDO2 "packed"
утверждение аттестата вместо?
3 ответа
Невозможно выбрать аттестацию с помощью таких простых ключей. Чтобы проверить мою реализацию для обеих аттестаций, я просто купил два разных ключа: один от Yibico и один от Nitrokey. Юбико отправляет fido-u2f, а Nitrokey отправляет упакованные аттестаты.
И если кому-то нравится знать, вот как я реализовал это:
let verifyAuthenticatorAttestationResponse = (webAuthnResponse) => {
let attestationBuffer =
base64url.toBuffer(webAuthnResponse.response.attestationObject);
let ctapMakeCredResp = cbor.decodeAllSync(attestationBuffer)[0];
let authrDataStruct = parseMakeCredAuthData(ctapMakeCredResp.authData);
let response = {'verified': false };
if(ctapMakeCredResp.fmt === 'fido-u2f' || ctapMakeCredResp.fmt === 'packed') {
if(!(authrDataStruct.flags & U2F_USER_PRESENTED))
throw new Error('User was NOT presented durring authentication!');
let clientDataHash =
hash(base64url.toBuffer(webAuthnResponse.response.clientDataJSON))
let publicKey = COSEECDHAtoPKCS(authrDataStruct.COSEPublicKey)
let PEMCertificate = ASN1toPEM(ctapMakeCredResp.attStmt.x5c[0]);
let signature = ctapMakeCredResp.attStmt.sig;
let signatureBase;
if(ctapMakeCredResp.fmt === 'fido-u2f') {
signatureBase = Buffer.concat([Buffer.from([0x00]), authrDataStruct.rpIdHash, clientDataHash, authrDataStruct.credID, publicKey]);
} else {
signatureBase = Buffer.concat([ctapMakeCredResp.authData, clientDataHash]);
}
response.verified = verifySignature(signature, signatureBase, PEMCertificate)
if(response.verified) {
response.authrInfo = {
fmt: `${ctapMakeCredResp.fmt}`,
publicKey: base64url.encode(publicKey),
counter: authrDataStruct.counter,
credID: base64url.encode(authrDataStruct.credID)
}
}
}
return response
}
По умолчанию браузер может выбрать U2F. Попробуйте форсировать UV, установив его на «требуемый». Это заставит браузер использовать FIDO2, поскольку U2F не поддерживает UV.
В соответствии с текущей спецификацией / стандартом, я не думаю, что вы (выступая в качестве проверяющей стороны) можете "выбрать", какой формат заявления об аттестации вы получаете от Аутентификатора (то есть "устройства"). Это решение, принятое Аутентификатором.
Я думаю, что аутентификатор платформы MacBook Pro TouchID через Chrome Desktop отправляет "упакованные" заявления об аттестации, если это поможет.