WebAuthn

A better alternative for securing our sensitive information online
 

Our online existence is built on passwords.

Often a password is all that lies between a malicious user and our bank accounts, social media accounts, and other sensitive data.

Passwords have an ever-growing list of problems associated with them, both for users and developers. Users have to worry about passwords being stolen by phishing tools, or their passwords being leaked online if websites they have accounts with are compromised. They have to worry about creating and remembering passwords without dedicated password management tools. Developers have to worry about all the complications of passing passwords through systems and safely storing them in databases.

The results are clear.

81%

of all hacking-related breaches leverage stolen or weak passwords.

One of the primary weaknesses of password-based authentication is that a password is a shared secret.

The password is the single key that proves you are in fact you. If a hacker manages to steal it, they can fully impersonate you unless you are one of the 28% of users using two-factor authentication.

There is a better way forward.

Introducing Public Key Cryptography and Web Authentication (WebAuthn)

The Web Authentication API (also known as WebAuthn) is a specification written by the W3C and FIDO, with the participation of Google, Mozilla, Microsoft, Yubico, and others. The API allows servers to register and authenticate users using public key cryptography instead of a password.

It allows servers to integrate with the strong authenticators now built into devices, like Windows Hello or Apple’s Touch ID. Instead of a password, a private-public keypair (known as a credential) is created for a website. The private key is stored securely on the user’s device; a public key and randomly generated credential ID is sent to the server for storage. The server can then use that public key to prove the user’s identity.

The public key is not secret, because it is effectively useless without the corresponding private key. The fact that the server receives no secret has far-reaching implications for the security of users and organizations. Databases are no longer as attractive to hackers, because the public keys aren’t useful to them.

WebAuthn is part of the FIDO2 framework, which is a set of technologies that enable passwordless authentication between servers, browsers, and authenticators. As of January 2019, WebAuthn is supported on Chrome, Firefox, and Edge, and Safari.

What is Public Key Cryptography?

Public key cryptography was invented in the 1970s, and was a solution to the problem of shared secrets. It is a pillar of modern internet security; for example, every time we connect to an HTTPS website, a public key transaction takes place.

Public key cryptography uses the concept of a keypair; a private key that is stored securely with the user, and a public key that can be shared with the server. These "keys" are long, random numbers that have a mathematical relationship with each other.

Web Authentication relies on three major properties:

Strong

Authentication is ideally backed by a Hardware Security Module, which can safely store private keys and perform the cryptographic operations needed for WebAuthn.

Scoped

A keypair is only useful for a specific origin, like browser cookies. A keypair registered at 'webauthn.guide' cannot be used at 'evil-webauthn.guide', mitigating the threat of phishing.

Attested

Authenticators can provide a certificate that helps servers verify that the public key did in fact come from an authenticator they trust, and not a fraudulent source.

Using the API

Registering a WebAuthn Credential

In a password-based user registration flow, a server will typically present a form to a user asking for a username and password. The password would be sent to the server for storage.

In WebAuthn, a server must provide data that binds a user to a credential (a private-public keypair); this data includes identifiers for the user and organization (also known as the "relying party"). The website would then use the Web Authentication API to prompt the user to create a new keypair. It is important to note that we need a randomly generated string from the server as a challenge to prevent replay attacks.

I want to create a new account.
Sure! Send me a public key.
All right! Creating a new keypair.
Okay, here's the public key!
Thanks! Registration complete.
navigator.credentials.create()

A server would begin creating a new credential by calling navigator.credentials.create() on the client.

const credential = await navigator.credentials.create({
    publicKey: publicKeyCredentialCreationOptions
});

The publicKeyCredentialCreationOptions object contains a number of required and optional fields that a server specifies to create a new credential for a user.

const publicKeyCredentialCreationOptions = {
    challenge: Uint8Array.from(
        randomStringFromServer, c => c.charCodeAt(0)),
    rp: {
        name: "Duo Security",
        id: "duosecurity.com",
    },
    user: