This repository is an experimentation that shows how the Web Authentication API works (called WebAuthn), and how this specification can be used to create a passwordless and usernameless authentification experiences (thanks to the resident keys). The code in this repository is not production-ready. Please, take into consideration concerns and comments in the note section before using it in production.
Watch this introduction to understand what is WebAuthn
All you need to do is install the dependencies needed
pnpm i
Run the frontend locally by running
pnpm dev
You can run the tests by running this command
# WIP
pnpm run test
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. It is a way better alternative for securing sensitive information online.
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 key pair (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 are 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.
As the Web Authentication API (also referred to as WebAuthn) uses asymmetric (public-key) instead of passwords or SMS texts for registering, authenticating, and second-factor authentication with websites, that unlock some benefits:
- Protection against phishing: An attacker who creates a fake login website can't login as the user because the signature changes with the origin of the website.
- Reduced impact of data breaches: Developers don't need to hash the public key, and if an attacker gets access to the public key used to verify the authentication, it can't authenticate because it needs the private key.
- Invulnerable to password attacks: Some users might reuse passwords, and an attacker may obtain the user's password for another website (e.g. via a data breach). Also, text passwords are much easier to brute-force than a digital signature.
WebAuthn is part of the FIDO2 framework, which is a set of technologies that enable passwordless authentication between servers, browsers, and authenticators. Nowadays WebAuthn is well supported.
- User is prompted to choose an available FIDO authenticator that matches the online service’s acceptance policy.
- User unlocks the FIDO authenticator using a fingerprint reader, a button on a second–factor device, securely–entered PIN or other method.
- User’s device creates a new public/private key pair unique for the local device, online service and user’s account.
- Public key is sent to the online service and associated with the user’s account. The private key and any information about the local authentication method (such as biometric measurements or templates) never leave the local device.
- Online service challenges the user to login with a previously registered device that matches the service’s acceptance policy.
- User unlocks the FIDO authenticator using the same method as at Registration time.
- Device uses the user’s account identifier provided by the service to select the correct key and sign the service’s challenge.
- Client device sends the signed challenge back to the service, which verifies it with the stored public key and logs in the user.
Snapshot taken on september 2022
This application is an experimentation, the code IS NOT PRODUCTION READY. If you want to use it as a base, please read the ressources linked below and pay attention to the comments that includes @TODO
. They need to be solved before envisaging using WebAuthn for real.
I made the choice, on the main branch, to use as few dependencies as possible. This means that I only use the official WebAuthn API, with its good and bad sides. One of the problems of the current state of the API is that some of the data returned by the autenticator is of type ArrayBuffer
. Even if this type is interesting for the WebAuthn use case, this makes it difficult for the manipulation and the communication with the backend. You can read more about this in the ongoing conversation about modifying the spec here. If you want to use this repository as a base, but want a version where the data returned by the autenticator is more "developer-friendly", I have pushed a branch that uses webauthnjson here.
Web Authentication: An API for accessing Public Key Credentials. Level 2 W3C specification
Web Authentication: An API for accessing Public Key Credentials. Level 3 W3C specification - DRAFT
Web Authentication API - MDN Documentation FIDO alliance official website
What is WebAuthn? - an illustrated explanation
What is WebAuthn? - by @Yubico
Introduction to WebAuthn API and Passkey
An web implementation of WebAuthn that uses nextjs
Discussion on the serialization/deserialization of webAuthn authenticator response