One-Time Password (OTP) Walk-Through

Overview

We are going to go through integrating the Yubico One-Time Password (OTP) protocol with your application or framework, step by step. This updated guide focuses on using the cloud-based YubiOTP validation service (YubiCloud) at api.yubico.com`.

Tip
This walk-through is designed for people who prefer learning by doing. If you prefer to learn concepts from the ground up, check out our YubiKey Authentication Module Design Guideline from 2012. The guide and this walk-through are complementary.

Try out our OTP demo at https://demo.yubico.com/otp/verify.

Overview of OTP

With One-Time Password (OTP), symmetric-key cryptography is used to authenticate users against a central server, known as a Relying Party (RP). The OTP is validated by a central server when users log into your application.

  • At production: A symmetric key is generated and loaded on the YubiKey. This can be done by Yubico for YubiCloud users or by the user directly.

  • OTP Generation: The YubiKey generates an OTP when a user requests to log in. This OTP is sent to the verification server (YubiCloud or a self-hosted server).

  • OTP Validation: The server validates the OTP and confirms that it belongs to the user.

Prerequisites

  • A computer with browser access

  • A YubiKey

Setup

Incorporating YubiKey authentication into your application involves the following components:

  1. Verification server: YubiCloud or a self-hosted server

  2. YubiKey API authenticator: YubiKey for generating OTPs

  3. Verification client: Your application’s logic for communicating with YubiCloud

  4. Authentication logic: Code for handling user registration and login

Enable Your YubiKey API Authenticator

  1. Sign up for and acquire your API key:

    • Go to the Yubico API key signup page.

    • Enter your email address and generate an OTP from your YubiKey.

    • Accept the Terms and Conditions and click "Get API key."

    • Record the Client ID and Secret Key. These values authenticate your users with the YubiCloud.

Create Your Verification Client

For this phase, you’ll create a client to communicate with the YubiCloud. Here’s a basic example using an HTTP GET request:

Using a Custom YubiCloud Client

  1. Send requests:

    ```
    const clientId = 'your-client-id';
    const secretKey = 'your-secret-key';
    const otp = 'generated-otp-from-yubikey';
    

const url = https://api.yubico.com/wsapi/2.0/verify?id=${clientId}&otp=${otp}&nonce=${generateNonce()}; fetch(url) .then(response ⇒ response.json()) .then(data ⇒ { if (data.status === OK) { console.log(OTP is valid); } else { console.error(OTP validation failed:, data.status); } }); ```

+ . Generate and verify signatures: * Use the Yubico OTP Validation Protocol Version 2.0 to construct and verify signatures. . Associated the YubiKey ID with the User ID * Modhex (modified hexadecimal) is a base-16 encoding method that YubiKeys use to ensure compatibility with different keyboard layouts. Here is an example of converting between hex and modhex in JavaScript:

+

```
// Convert hex to modhex
function hexToModhex(hex) {
  const modhexMap = {
    '0': 'c', '1': 'b', '2': 'd', '3': 'e', '4': 'f', '5': 'g', '6': 'h', '7': 'i',
    '8': 'j', '9': 'k', 'a': 'l', 'b': 'n', 'c': 'r', 'd': 't', 'e': 'u', 'f': 'v'
  };
  return hex.split('').map(char => modhexMap[char.toLowerCase()]).join('');
}

function modhexToHex(modhex) { const hexMap = { c: 0, b: 1, d: 2, e: 3, f: 4, g: 5, h: 6, i: 7, j: 8, k: 9, l: a, n: b, r: c, t: d, u: e, v: f }; return modhex.split(').map(char ⇒ hexMap[char.toLowerCase()]).join('); }

const hexKey = abcdef1234567890; const modhexKey = hexToModhex(hexKey); console.log(Modhex Key:, modhexKey);

const backToHex = modhexToHex(modhexKey); console.log(Back to Hex:, backToHex); ```

+ * Extract the YubiKey ID save to the user’s credential repository

+

```
// Example OTP from YubiKey
const otp = 'cccccccfhjfjkknvubekedkrncrkruvvkiutlfibngd';

const yubiID = otp.substring(0, 12); console.log(YubiID (modhex):, yubiID);

const hexYubiID = modhexToHex(yubiID); console.log(YubiID (hex):, hexYubiID); ```

Add Authentication Logic to Your Application

In your application, add the logic needed to process registration and authentication requests.

User Registration

  1. Expose a connection to your UI to accept the OTP for launching the application.

  2. Use the YubiKey Public ID to associate it with the registering user.

  3. Store the YubiKeyID : UserID pairs in your database.

  4. Add logic to check the UserID for a valid OTP response from the YubiCloud validation server.

User Authentication

  1. Retrieve the OTP from an inserted and tapped YubiKey.

  2. Pass the OTP to your YubiCloud client.

  3. Parse the YubiCloud response.

  4. Verify the YubiKey public ID against the user ID pair in your database.

  5. Authenticate the user if the OTP is valid.

Wrapping Up

Congratulations! You’ve completed the steps to enable your users to register and authenticate with an OTP credential.

Additional Resources

Deprecated Libraries

The following are deprecated and archived: