Search code examples
reactjsnode.jsauthenticationpublic-key-encryptionwebauthn

Webauthn - How to validate/verify returned registration auth data using React + Node.js


Trying to implement a basic webauthn flow in a React/Node app by following the official Webauthn guide. My call to navigator.credentials.create() is working and I'm successfully generating a PublicKeyCredential object for a given user; however I'm no auth expert and I'm not sure what to do next and how I should "validate" the returned auth data?

After the registration API succeeds I have the returned clientDataJSON and attestationObject (among other data). I'm able to verify the challenge in the client data matches the original challenge from initial request. Beyond that my decoded attestation object looks like the following:

{
  fmt: 'none',
  attStmt: {},
  authData: <Buffer 49 96 0d e5 88 0e 8c 68 74 34 17 0f 64 76 60 5b 8f e4 ae b9 a2 86 32 c7 99 5c f3 ba 83 1d 97 63 5d 00 00 00 00 fb fc 30 07 15 4e 4e cc 8c 0b 6e 02 05 ... 102 more bytes>
}

The guide then shows how to parse the returned auth data and sure enough I can parse the public key bytes getting an object such as:

{
    1: 2,
    3: -7,
    -1: 1,
    -2: Uint8Array(32) ...
    -3: Uint8Array(32) ...
}

However, now what do I do? The guide says "If the validation process succeeded, the server would then store the publicKeyBytes and credentialId in a database..."

What does "if validation process succeeded" mean, do I need to sign something using the public key to verify it's valid or some other cryptographic check?? (Sorry but I'm a relative auth n00b)


Solution

  • https://webauthn.guide is a great site, but since you've made it this far my recommendation is to give the WebAuthn spec a read. It goes into more step-by-step detail here on how an RP should process registration and authentication responses:

    https://w3c.github.io/webauthn/#sctn-registering-a-new-credential

    In your case you're around Step 12, which introspects the various flags within authData. At Step 21 you'll start evaluating the value of attStmt based on the value of fmt. The value of fmt is "none" in your example so there won't be a whole lot to do. Assume that attestation verification "completed successfully" in the subsequent steps and you'll be good to go.

    ...do I need to sign something using the public key to verify it's valid or some other cryptographic check??

    Fun fact: no signature is present when "none" attestations are returned, so you won't be using the public key for anything during registration in this particular scenario!