There’s been a lot of news lately about the new W3C Web Authentication API, also known as WebAuthn. Want to know what it’s all about? Let’s take a closer look.
The Web Authentication API allows browsers to make use of hardware authenticators such as the Yubikey or a mobile phone’s biometrics, like a thumbprint reader or facial recognition. WebAuthn can be used with these technologies to enable two-factor authentication to websites, or even as the primary authentication mechanism.
Much of the motivation behind the development of the spec is to reduce reliance on passwords or other authentication methods that are easily phished. The effort began under the FIDO Alliance, and was adopted by the W3C to create the WebAuthn spec as the major browser vendors got on board.
How Does WebAuthn Work?
Under the hood, the WebAuthn spec uses public key cryptography to provide a way for browsers to sign a challenge using a private key stored by the operating system or on a physical hardware token. The private key never leaves the device, and is never made available to the browser. For hardware tokens like the Yubikey, the private key isn’t even accessible to the underlying operating system!
If you already have existing users with an existing authentication mechanism, letting users enroll a WebAuthn credential will work something like this:
- Have your users log in using their existing credentials
- Create a new WebAuthn credential and associate it with the user account
- When the user returns, prompt them for their WebAuthn credential, and once verified, you can sign them in
A unique property of the WebAuthn API is that it can’t be used to identify users between different websites. The credentials generated are tied to the domain of the website that generated them. This provides an additional layer of privacy to users, since websites can’t use the WebAuthn credential to identify users across domains.
The WebAuthn JavaScript API
The WebAuthn spec defines two new JavaScript APIs available to web applications: navigator.credentials.create
and navigator.credentials.get
.
You’ll use the navigator.credentials.create
function to enroll a new authenticator and store the resulting identifier at your server. To set up a new authenticator, you’ll first need to generate 32 random bytes on the server, and provide that to your JavaScript function. These 32 random bytes are part of the data that the authenticator will sign, so it’s important that this be generated by your server so your server knows that the resulting signed challenge was one that it initiated.
When you want to ask the user to log back in with an existing credential, you can use the navigator.credentials.get
function to request that the user prove the possession of an existing enrolled device. If they’ve registered multiple devices, you can pass multiple identifiers to the function and the matching one will be returned.
When the site runs the navigator.credentials.create
function, all available USB keys or other authentication mechanisms will wait for the user to interact with them. In the case of Yubikeys, you’ll see the blinking light on all of them that are currently plugged in. If you specify an existing identifier to the navigator.credentials.get
function, then only that one key will blink.
See Mozilla’s Using Hardware Token-based 2FA with the WebAuthn API guide for more details on the JavaScript code necessary to make this work.
When Can I Use WebAuthn?
As of April 2018, the WebAuthn API is available in Firefox Nightly, and can be turned on in Chrome by enabling a setting in chrome://flags
. Apple has not yet commented on whether or when WebAuthn will be available in Safari. They were involved with the development of the spec, though, so they will likely be shipping it soon.
The spec itself is currently a W3C “Candidate Recommendation”, which is the second to last step before it’s finalized as a “Recommendation.”