Javascript WebAuthn检索公钥和凭据id

Javascript WebAuthn检索公钥和凭据id,javascript,buffer,webauthn,Javascript,Buffer,Webauthn,我遵循了这个教程 我正在使用yubico nfc密钥,我几乎成功注册了安全密钥。 我从服务器发送一个随机字节挑战来注册密钥和其他数据 当我注册密钥时,我设法解码clientDataJson和身份验证响应以检索大量信息。 然而,我无法弄清楚如何处理credentialId和authData缓冲区,我尝试对它们进行解码和解密,但我总是得到一些奇怪的数据,并且没有任何看起来像credentialId或公钥的数据 这是我到目前为止得到的代码 var createCredentialDefaultArg

我遵循了这个教程

我正在使用yubico nfc密钥,我几乎成功注册了安全密钥。 我从服务器发送一个随机字节挑战来注册密钥和其他数据

当我注册密钥时,我设法解码clientDataJson和身份验证响应以检索大量信息。 然而,我无法弄清楚如何处理credentialId和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);
                    });
            })
最后,我不知道该如何处理公钥对象和凭证ID。去编码似乎没用

有什么想法吗?

和值都是非字节字符串

关于如何处理它们。您可以将它们存储在数据库或服务器正在使用的任何其他长期存储中的用户数据旁边,这样您就可以将它们用作未来身份验证仪式的输入。

和值都是非字节字符串

关于如何处理它们。您可以将它们存储在数据库或服务器正在使用的任何其他长期存储中的用户数据旁边,这样您就可以将它们用作未来身份验证的输入

我总是得到一些奇怪的数据,没有什么看起来像是有身份证明的身份证或公钥

这是因为两者都是字节序列

从authData解析的credentialId是一个随机字节字符串,通常由U2F键生成96字节长,因此不要指望这些字节有意义

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
}
最后,我不知道该如何处理公钥对象和凭证ID

您需要凭据ID来标识尝试根据您的网站进行身份验证的用户,并需要公钥来验证其身份

从authData响应中提取的所有其他信息都应该经过验证,但不需要保留,只需保存credentialId和publicKeyBytes对即可

本网站详细介绍了认证过程:

要了解如何验证签名,请检查此链接:

我总是得到一些奇怪的数据,没有什么看起来像是有身份证明的身份证或公钥

这是因为两者都是字节序列

从authData解析的credentialId是一个随机字节字符串,通常由U2F键生成96字节长,因此不要指望这些字节有意义

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
}
最后,我不知道该如何处理公钥对象和凭证ID

您需要凭据ID来标识尝试根据您的网站进行身份验证的用户,并需要公钥来验证其身份

从authData响应中提取的所有其他信息都应该经过验证,但不需要保留,只需保存credentialId和publicKeyBytes对即可

本网站详细介绍了认证过程:

要了解如何验证签名,请检查此链接: