Home / Security and Auth / TOTP 2FA Authenticator

TOTP 2FA Authenticator in JavaScript, Free with Live Demo

Free TOTP authenticator in plain JavaScript. Make six digit 2FA codes with HMAC-SHA1, add accounts from a secret or otpauth link, make QR codes and verify codes.

Open live demoDownload HTML fileView code on GitHub
TOTP 2FA Authenticator JavaScript project: an authenticator app that makes six digit 2FA codes

Runs on: TOTP, RFC 6238. Every modern browser. Secrets are stored unencrypted in this demo, so do not use it for real accounts.

What is the TOTP 2FA Authenticator?

The six digit codes in apps like Google Authenticator come from a shared secret and the current time. This project does that math live for as many accounts as you like, with a countdown ring for each code.

It follows RFC 6238. The current time is split into 30 second steps, the step number is signed with HMAC-SHA1 using your secret, and a short part of the result becomes the code. The page is tested against the official test values.

Good for

  • Learning how 2FA codes work
  • Adding 2FA to your own app
  • Testing login flows
  • Security interviews and courses

What this project does

How it works

  1. Count time stepsThe current Unix time is divided by 30 to get a counter that changes every 30 seconds.
  2. Sign the counterThe counter, as 8 bytes, is signed with HMAC SHA-1 using the account's secret as the key.
  3. TruncateFour bytes are picked from the signature using its last nibble, turned into a number, and cut to 6 digits.

The key JavaScript

This is the heart of the project. The full file has the rest, including the screen layout and error handling.

async function totp(base32Secret, step = 30, digits = 6) {
  const counter = Math.floor(Date.now() / 1000 / step);
  const msg = new DataView(new ArrayBuffer(8));
  msg.setUint32(4, counter);                              // 8 byte big-endian counter
  const key = await crypto.subtle.importKey("raw", base32Decode(base32Secret),
    { name: "HMAC", hash: "SHA-1" }, false, ["sign"]);
  const h = new Uint8Array(await crypto.subtle.sign("HMAC", key, msg.buffer));
  const o = h[19] & 0xf;                                  // dynamic truncation
  const n = ((h[o] & 0x7f) << 24) | (h[o + 1] << 16) | (h[o + 2] << 8) | h[o + 3];
  return String(n % 10 ** digits).padStart(digits, "0");
}

How to use it

  1. Click Download HTML file above.
  2. Open the file in a code editor, like VS Code.
  3. Run it from a local server with npx serve . so the camera, microphone and AI features are allowed.
  4. Change the text and colors, then upload it to GitHub Pages, Netlify or your own site. It is one file with no build step.

Questions people ask

How does TOTP work?

The server and your app share a secret. Both sign the current 30 second time step with it, so they get the same six digit code without talking to each other.

Can I use this instead of Google Authenticator?

It is a learning project and stores secrets without encryption, so keep using a real authenticator for your accounts.

Why was my code rejected?

Usually the device clock is off. This project accepts one step before and after to allow for small drift.

More Security and Auth projects