TOTP / 2FA Generator

TOTP / 2FA Generator

Generate and verify time-based one-time passwords from a Base32 secret or otpauth URI, entirely in this browser.

Generate a codeRFC 6238-compatible local calculation
Current code
Enter a secret to calculate
Local calculation30s remaining
Verify a codeChecks current and adjacent periods
Waiting for a codeUse the generated code or paste one from an authenticator app.

A valid code confirms only that the secret and clock window match. It does not enroll an account or prove ownership.

Use synthetic secrets for testing. Never paste a live production authenticator secret into a shared screen.

Copy TOTP codeEnvironment variables keep credentials out of copied code
import { createHmac } from "node:crypto";

const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
function decodeBase32(value) {
  let buffer = 0; let bits = 0; const bytes = [];
  for (const character of value.replace(/=+$/, "").toUpperCase()) {
    const index = alphabet.indexOf(character);
    if (index < 0) throw new Error("Invalid Base32 secret");
    buffer = (buffer << 5) | index; bits += 5;
    if (bits >= 8) { bits -= 8; bytes.push((buffer >> bits) & 255); }
  }
  return Buffer.from(bytes);
}
const key = decodeBase32(process.env.TOTP_SECRET ?? "JBSWY3DPEHPK3PXP");
const counter = Math.floor(Date.now() / 1000 / 30);
const counterBytes = Buffer.alloc(8); counterBytes.writeBigUInt64BE(BigInt(counter));
const digest = createHmac("sha1", key).update(counterBytes).digest();
const offset = digest[digest.length - 1] & 15;
const code = ((digest[offset] & 127) * 2 ** 24 + digest[offset + 1] * 2 ** 16 + digest[offset + 2] * 2 ** 8 + digest[offset + 3]) % 10 ** 6;
console.log(String(code).padStart(6, "0"));