How Things Work in WebAuthn
Web Authentication API, also referred to as WebAuthn enables better and strong authentication of users by using public-key cryptography. WebAuthn defends users against phishing attacks, reduces the impact of data breaches and it is invulnerable to password attacks. Basically, WebAuthn is a W3C standard and is also used as a sub-specification of FIDO2 specifications.
public-key cryptography
Before moving forward, let’s look at what is public-key cryptography. In cryptography, we use a single key for encryption and we need to pass both the encrypted content and the key to the sink securely. But in public-key cryptography, we have a key pair namely, the public key and the private key. If we encrypt with one key (public key or the private key) we only can decrypt with the other key and it works the other way around as well. So we encrypt our data with our private key which is kept secret and pass the signed data and expose the public key. The sink who receives signed data can prove the sender’s identity by decrypting it with the senders public key. If you are interested in cryptography, I recommend you to explore more on other cryptographic concepts like elliptic curve cryptography. A basic idea of public-key cryptography is important when it comes to WebAuthn standards.
Conformance Classes
There are 3 major conformance classes or simply think of it as components in WebAuthn specifications, Authenticator, User Agent (Browser), Relying party (Web Application). This clear division of components provides flexibility and security.
User-Agent
User-agent or the web browser stays in between the authenticator and the relying party. It is responsible for various validation and verification tasks. You will encounter more details later.
Authenticators
In WebAuth specifications, the WebAuthn authenticator model defines the logical operations that authenticators must support and data formats that should be exposed. Each and every authenticator has it’s own unique AAGUID number indicating manufacturer details and model details. Authenticator attachment modality or in simple terms how these devices are connected to the user’s device are of two types,
Platform authenticators — Where the authenticating mechanism is built into the device. For example, a laptop with a fingerprint scanner or a mobile phone with a fingerprint scanner.
Roaming authenticators — Devices used when devices lack platform authenticators. Normally they are connected to the user’s device via USB port or Bluetooth technology.
Apart from all these details, the primary function of the authenticator is to provide WebAuthn signatures. The authenticator signs the client data and authenticator data and produce two types of signatures,
attestation signature — produced when creating new public-key credentials
assertion signature — produced in the authentication scenario0
There are two credential storage modalities, persistent storage embedded in the authenticator or the client, and storage on the relying party by sending the encrypted format of the private key.
An authenticator performs several operations such as create credentials and get credentials.
Relying Party
Relying Party is the web application where the user requests the services. It can be any application that the user wants to create an account.
You will come across more details on these three components when it comes to registration and authentication flow.
There are two major scenarios when it comes to WebAuthn specifications, the registration scenario and the authentication scenario. Simply you can consider registration as signup to a web application and authentication as a login.
Registration
- Initially the user sends a registration request to the relying party or might login with the existing user credentials and request for key registration.
- The relying party in return will request with publicKeyCredentialCreationOptions variable which contains a challenge, user information (user) and relying party information (rp).
challenge — A long randomly generated variable sent by the relying party. Used to mitigate replay attacks
rp — relying party information such as name and id. The id is usually the relying party URL which is used to avoid phishing attacks.
user — User information such as id, name, displayName - The client application will invoke the navigator.credentials.create() function which takes publicKeyCredentialCreationOptions and the two variables relying party id and clientDataHash that are generated by the browser as the argument for the function.
rpId — Relying party identifier
clientDataHash — The hashed version of the serialized clientDataJSON - Then the Attestation process, where the authenticator comes into play. Initially, The authenticator will require the user to either show presence or verify himself/herself with a pin or any other biometrics mechanism. With the consent, the authenticator will create a public and private key pair where the private key is stored safely and the public key will become a part of the attestation which is passed to the relying party. And the attestation will be created by signing relying party details (rpId), the public key generated, hashed client data (clientDataHash) with the key burned to the authenticator during manufacture. Finally, the authenticator creates attestationObject with the signed data a globally unique credential id, newly created public key, certificates and pass it on to the browser.
attestationObject — Contains the newly generated public key, credential id and attestation
certificate — A X.509 Certificate to verify the attestation signature used by the authenticators. - The browser will send authenticatorAttestationResponse to the relying party. authenticatorAttestationResponse contains,
id — Identification for the response
rawId — Globally unique credential identification
attestationObject — Contains the newly generated public key, credential id and attestation.
clientDataJSON — encapsulate challenge is given by the relying party, hashing algorithms used, origin which is the URL of the relying party - At the relying party end there are several verification and validations done. At a higher level,
verification of the challenge
verification of the origin
verifies the signature
verifies the counter
verifies the certificate chain
Finally, the user is registered into the system and is fit for the authentication scenario
Authentication
When it comes to the authentication scenario, the user proves (assert) that he/she has the private key which is associated with the public key that is stored in the relying party database linked to the account. Let’s see how the authentication scenario happens,
- The user will initiate the authentication process by sending a request to the relying party.
- The relying party sends publicKeyCredentialRequestOptions which contain a challenge to the client.
- The navigator.credentials.get(publicKeyCredentialRequestOptions) will be invoked by the WebAuthn.
- User agent will pass ‘relying party id’(rpId) and clientDataHash to the authenticator. The authenticator will find the related credentials that match the ‘relying party Id’. Then the user is prompted to confirm his/her presence or even to verify using a pin or any other biometric mechanism. An attestation object will be formed by signing the data with the private key produced during the registration scenario. The authenticator will return an attestationObject by signing over the clientDataHash and authenticator data and will return both assertion signature and authenticator data to the browser.
rpId — Relying party identifier
clientDataHash — The hashed version of the serialized clientDataJSON - The Browser will send authenticatorAssertionResponse to the relying party which encapsulates clientDataJSON, authenticator data and the signature.
clientDataJSON — encapsulates the challenge given by the relying party, hashing algorithms used, origin which is the URL of the relying party - At the relying party end, the server will perform a series of verifications
verify the challenge
verify the origin
verify the signature
verify the counter
Finally, the user will be successfully authenticated into the relying party system.
These two flows might look very similar, but the difference is that,
In the authentication scenario, the authenticator doesn’t require user data or relying party information
In the registration scenario, the authenticator will sign the required data with a private key that is burned into the authenticator, but in the authentication scenario, it will use a previously created private key for that particular relying party to sign the data.
Hope you have a better grasp of how things work in WebAuthn. Want to explore more on these topics? Stay tuned! more stories are on the way.
See you soon!