0

I have mocked up the response from the front end in Node.js as seen below.

the attestationObject parameter is what is returned once the Yubikey has signed the challenge and its been converted to base64 for transport to the node server.

What i'm getting is an ArrayBuffer { byteLength: 226 } but I have no idea what to do with it.

I know i need to check the domain name the signed it and I need to store something with the users credentials so they can login again.

I understand there is loads of options, I just want to get a bare minimum passwordless register and login working.

const cbor = require("cbor");
const attestationObject = "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjE4mQ5WmgO3yl24XjxRqkP9LjqRYP-GsIubALB-5K_CK5FXMrOUa3OAAI1vMYKZIsLJfHwVQMAQABcapsmHtrsLJtfZ7RDcRm0iDgMlc5-CuP2XcNOwDy0uU2mU44ENk-EqtthH7huq8AipYfY0EvmfPRqQI-zI5GlAQIDJiABIVggZplpmQSKsJvg78INyrQUgBo9dv0vaZL6Qp15rOd6wMQiWCAx-ZeQ6T_xTMlY9cG3EWY54wT9Hd6EX7P7Ak-9uwauCA"
const clientDataJSON = "eyJjaGFsbGVuZ2UiOiJlVGR1TjJGaGFIaHhhRFJzT0RsdU1qTnRhMjgiLCJvcmlnaW4iOiJodHRwczovL2UzMDI3MTU3Lm5ncm9rLmlvIiwidHlwZSI6IndlYmF1dGhuLmNyZWF0ZSJ9"
const id = "AFxqmyYe2uwsm19ntENxGbSIOAyVzn4K4_Zdw07APLS5TaZTjgQ2T4Sq22EfuG6rwCKlh9jQS-Z89GpAj7MjkQ"
const rawid = "AFxqmyYe2uwsm19ntENxGbSIOAyVzn4K4_Zdw07APLS5TaZTjgQ2T4Sq22EfuG6rwCKlh9jQS-Z89GpAj7MjkQ"

convertToBuffer(attestationObject)
.then((buffer) => {
 return parseAttestationObject(buffer)
})
.then((json) => {
    console.log(json)
})
.catch((err) => {
    console.log(err)
})

function convertToBuffer(base64) {
    return new Promise((resolve, reject) => {
        if (typeof base64 === "string") {
            base64 = base64.replace(/-/g, "+").replace(/_/g, "/");
            base64 = Buffer.from(base64, "base64");
            base64 = new Uint8Array(base64);
            resolve(base64.buffer);
        }

    })
}

function parseAttestationObject(attestationObject){
    return new Promise((resolve, reject) => {
        const authData = cbor.decodeAllSync(Buffer.from(attestationObject));
        const authnrDataArrayBuffer = authData[0].authData.buffer;
        console.log(authnrDataArrayBuffer)
        // What do I do with this authnrDataArrayBuffer? What needs saving to the database?
    }) 
}
Bill
  • 4,614
  • 13
  • 77
  • 132

2 Answers2

0

It would be helpful if you would be a bit more exact about the exact issue, but in a nutshell:

  • You'd want to store the rawI This is the identifier that you need to pass in the allowCredentials object in the authentication step, so you'll need it.
  • The attestationobject is a CBOR encoded value. After some manipulations you should be able to extract a public key from this. You'll be able to to use this certificate to verify the response from the authenticator in the authentication step.

I'm leaving out any specific implementation steps, but please have a look at https://github.com/fido-alliance/webauthn-demo as this project implements webauthn for node.js as well, so you should be able to extract all relevant code from it.

vixducis
  • 1,010
  • 1
  • 8
  • 22
0
// this is your attestationObject which is web safe base64 encode string
var attestationObject = "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjE4mQ5WmgO3yl24XjxRqkP9LjqRYP-GsIubALB-5K_CK5FXMrOUa3OAAI1vMYKZIsLJfHwVQMAQABcapsmHtrsLJtfZ7RDcRm0iDgMlc5-CuP2XcNOwDy0uU2mU44ENk-EqtthH7huq8AipYfY0EvmfPRqQI-zI5GlAQIDJiABIVggZplpmQSKsJvg78INyrQUgBo9dv0vaZL6Qp15rOd6wMQiWCAx-ZeQ6T_xTMlY9cG3EWY54wT9Hd6EX7P7Ak-9uwauCA";

// need to convert to base64 encode string
attestationObject = attestationObject.replace(/\-/g, '+').replace(/_/g, '/') + '=='.substring(0, (3*attestationObject.length)%4);

// do a base64 decode
var attCbor = Buffer.from(attestationObject, 'base64');

// decode to have CBOR object, using cbor module
const cbor = require("cbor");
var attCborObj = cbor.decodeAllSync(attCbor)[0];
console.log(attCborObj);
Robert
  • 39,162
  • 17
  • 99
  • 152
Bao HQ
  • 1,145
  • 7
  • 18