WebAuthn получает открытый ключ и идентификационный номер - PullRequest
1 голос
/ 09 апреля 2019

Я следовал этому уроку https://webauthn.guide/#registration

Я работаю с ключом yubico nfc, и мне почти удалось зарегистрировать ключ безопасности. Я посылаю случайный байт с сервера для регистрации ключа и других данных.

Когда я зарегистрировал ключ, мне удалось декодировать clientDataJson и ответ аутентификации для получения большого количества информации. Однако я не могу понять, что делать с буферами credentialId et authData, я пытался их расшифровать, расшифровать, но я всегда получал некоторые странные данные и ничего похожего на credentialId или открытый ключ.

Вот код, который я получил до сих пор

 var createCredentialDefaultArgs = {
            publicKey: {
                // Relying Party (a.k.a. - Service):
                rp: {
                    name: 'Dummy'
                },

                // User:
                user: {
                    id: new Uint8Array(16),
                    name: 'John Doe',
                    displayName: 'Mr Doe'
                },

                pubKeyCredParams: [{
                    type: "public-key",
                    alg: -7
                }],

                attestation: "direct",

                timeout: 60000,

                challenge:  new Uint8Array(/* stuff*/).buffer
            }
        };


        $('[data-register-webauthn]')
            .on('click', function () {
                // register / create a new credential
                navigator.credentials.create(createCredentialDefaultArgs)
                    .then((cred) => {
                        console.log("NEW CREDENTIAL", cred);

                        const utf8Decoder = new TextDecoder('utf-8');

                        const decodedClientData = utf8Decoder.decode(cred.response.clientDataJSON);

                        // parse the string as an object
                        const clientDataObj = JSON.parse(decodedClientData);

                        const decodedAttestationObj = CBOR.decode(cred.response.attestationObject);

                        const {authData} = decodedAttestationObj;
                        // get the length of the credential ID
                        const dataView = new DataView(new ArrayBuffer(2));
                        const idLenBytes = authData.slice(53, 55);
                        idLenBytes.forEach(
                            (value, index) => dataView.setUint8(
                                index, value)
                        );
                        const credentialIdLength = dataView.getUint16();

                        // get the credential ID
                        const credentialId = authData.slice(
                            55, credentialIdLength);

                        // get the public key object
                        const publicKeyBytes = authData.slice(
                            55 + credentialIdLength);

                        // the publicKeyBytes are encoded again as CBOR
                        const publicKeyObject = CBOR.decode(
                            publicKeyBytes.buffer);
                        console.log(publicKeyObject)
                    })
                    .catch((err) => {
                        console.log("ERROR", err);
                    });
            })

В конце концов, я не знаю, что делать с объектом открытого ключа и идентификатором credentialId. Deconding кажется бесполезным.

Есть идеи?

Ответы [ 2 ]

3 голосов
/ 11 апреля 2019

Я всегда получал какие-то странные данные и ничего похожего на идентификатор доступа или открытый ключ.

Это потому, что оба являются байтовыми последовательностями.

credentialId, который вы проанализировали с authData, представляет собой строку случайных байтов (обычно длиной 96 байт), генерируемых ключом U2F, поэтому не ожидайте, что они будут иметь смысл.

Переменная publicKey немного сложнее, так как она кодируется CBOR (не вашей обычной строкой PEM), которая после декодирования в publicKeyObject должна дать вам вывод, подобный следующему:

{
   1: 2,              // Ellipic Curve key type
   3: -7,             // ES256 signature algorithm
  -1: 1,              // P-256 curve
  -2: 0x7885DB484..., // X value
  -3: 0x814F3DD31...  // Y value
}

В конце концов, я не знаю, что делать с объектом открытого ключа и идентификатором credentialId.

Вам понадобится Идентификатор удостоверения * от 1022 * до , идентифицирующий пользователя, который пытается аутентифицироваться на вашем сайте, и от Открытый ключ до проверки его личность.

Вся остальная информация, извлеченная из ответа authData, должна быть проверена, но нет необходимости сохранять ее, просто сохраните пару credentialId и publicKeyBytes.

Этот веб-сайт объясняет процесс аутентификации достаточно подробно: https://webauthn.guide/#authentication

Чтобы узнать, как проверить подпись, перейдите по этой ссылке: https://w3c.github.io/webauthn/#fig-signature

0 голосов
/ 09 апреля 2019

Идентификатор удостоверения и Открытый ключ удостоверения * Значения не являются приемлемыми для человека байтовыми строками.

По поводу того, что с ними делать. Вы храните их рядом с пользовательскими данными в своей базе данных или любом другом долговременном хранилище, которое использует ваш сервер, поэтому вы можете использовать их в качестве входных данных для будущих церемоний аутентификации.

...