Yubikey Second-Factor Authentication implementation in one afternoon (or less).

Nowadays, anyone can get a hardware key for as little as $20.

Hardware keys or "yubikeys" as they are commonly called, are more practical and easier of use than the alternatives (SMS and OTP).

Any respectable online service should allow it's users to use such a tool.

Here you can see all the services that already support yubikey.


Hands on implementation (Javascript)

First of all, install the u2f module:

npm install u2f

Load the module in the backend:

Add this line to the Frontend to enable the window.u2f functionality.

Note: Only Google Chrome supports this natively at the moment. (In other words, more than 53% of the users will be covered, the rest will have to use SMS or OTP).

Link a yubikey to an account

Steps to link a new yubikey to an account:

  1. Generate a challenge in the Backend, send it to the Frontend.
  2. Sign the challenge in the Frontend (using the yubikey), return it to the Backend for verification.
  3. If the signature is correct, save the publicKey and keyHandle of the user to be used for all future login verifications.

Here is how to really do it:

1. Generate the challenge (Backend)

2. User signs the challenge with the yubikey (Frontend)

The callback is executed only when the user plugs in the yubikey and presses the button in it, so it's a good moment to notify the user, maybe use an animation like this, to help the user understand what he must do.

3. Verify signature (Backend)

That's it, now that you have the publicKey and the keyHandle of his yubikey, you can verify that the user is who he says he is, every time he wants to login.

Verify yubikey at login

To verify a user using his yubikey, follow these three steps:

  1. Generate a challenge in the Backend, send it to the Frontend.
  2. Sign the challenge in the Frontend (using the yubikey), return it to the Backend for verification.
  3. If the signature is correct, save the publicKey and keyHandle of the user to be used for all future login verifications.

Again, here is how to do it:

1. Generate the challenge (Backend)

2. User signs the challenge with the yubikey (Frontend)

The window.u2f.sign() doesn't return until the user inserts the yubikey and presses the button, so, tell the user to do so, maybe use this animation, to help the user understand what he must do.

3. Verify signature (Backend)

That's it, you now have a secure and practical way for users to verify their identity.

PD: There is a new Yubikey 2 that allows FIDO2 passwordless authentication, which means that the user won't even need to remember a password 😎