Skip to main content

TOTP Generator

Generate time-based one-time passwords (TOTP) from a base32 secret with live 30-second countdown.

Reviewed by · Last reviewed

Generating a 2FA Code from a Base32 Secret

  1. Paste the base32 secret into the input. Most sites display it on the 2FA setup page under "Can\'t scan the QR code?" or "Manual entry". Valid base32 uses only A-Z and 2-7; padding = is optional.
  2. Watch the code appear. The tool computes the current 6-digit TOTP and displays it with a 30-second countdown ring that refreshes the code at each window boundary.
  3. Copy the digits by clicking the code itself or the copy button. The code is valid for the remaining seconds on the ring plus one window on either side on most servers.
  4. Enter the code into the login field of the service. If it is rejected, check your device clock - TOTP is time-sensitive down to the second.
  5. Wait 30 seconds for a fresh code if the current one is close to expiry. Do not type a code that has less than 3 seconds remaining; network latency alone can push it past the window.

Inside the 30-Second Magic: HOTP, TOTP, HMAC-SHA-1

TOTP is specified in RFC 6238 and builds on HOTP (RFC 4226). The algorithm: TOTP = Truncate(HMAC-SHA-1(K, T)) where K is the base32-decoded secret and T = floor((currentUnixTime - T0) / X), with T0 = 0 and X = 30 seconds. The tool decodes base32 into the HMAC key, packs the time window as an 8-byte big-endian integer, computes HMAC-SHA-1 via crypto.subtle.sign, then applies dynamic truncation (RFC 4226 section 5.3): low 4 bits of the last byte as offset, read 4 bytes there, mask the top bit, modulo 10^6. Google Authenticator, Authy, Microsoft Authenticator all use these exact defaults.

When You Reach for a Standalone TOTP Tool

  • Testing a freshly provisioned 2FA integration during development, where you have the secret but do not want to pollute your personal authenticator with test entries.
  • Recovering access after losing your phone when you saved the base32 secret in a password manager rather than only the QR code.
  • Debugging why your users\' codes are being rejected: paste the same secret your backend stores and check whether it matches Google Authenticator.
  • Automating 2FA in a CI pipeline for end-to-end tests against a staging environment where pure-JavaScript test code needs to log in.
  • Building a custom authenticator app and wanting a known-good reference to validate your TOTP implementation against.
  • Generating a 2FA code on a desktop when your phone is out of reach, using the secret backed up to a password manager.

Clock Drift, Base32 Padding, and Secret Storage Pitfalls

The most common TOTP failure is clock drift. If your clock is more than 30 seconds off wall time, codes are rejected. Servers typically accept plus/minus one window tolerance (RFC 6238 section 5.2), so up to a minute of drift survives; beyond that, sync with NTP. Second pitfall: base32 decoding. Copying a secret can introduce lowercase letters, spaces, or digits 0/1 that are not valid base32. The tool strips whitespace and upper-cases before decoding. Third: the secret is bearer-level - treat it like a password, store in a manager, revoke if it leaks. Fourth: some services use non-standard parameters (6 vs 8 digits, 30 vs 60 second windows, SHA-256 instead of SHA-1). This tool implements defaults; if a service uses non-defaults, Google Authenticator also will not work.

Why TOTP Uses HMAC-SHA-1 in 2026

HMAC-SHA-1 remains the TOTP default despite SHA-1 collision attacks because HMAC\'s security does not depend on collision resistance - only on the pseudo-random-function property, which SHA-1 still has. The 2017 SHAttered attack and the 2020 Chosen-Prefix Collision against SHA-1 broke certificate signing, not HMAC. RFC 6238 section 1.2 explicitly notes that HMAC-SHA-256 and HMAC-SHA-512 variants exist and can be requested via otpauth:// URI parameters, but the installed base of Google Authenticator and compatible apps defaults to SHA-1, so most services stick with the default for interoperability. The truncation to 6 digits is deliberate: it limits the tag to around 20 bits of unpredictability per 30-second window, but combined with rate limiting on the server (lockout after 5-10 wrong codes) the effective attacker success rate is roughly one in a million per lockout interval - acceptable because the secret rotates every 30 seconds. Longer codes (7 or 8 digits) add security against online attacks at the cost of user friction; most services chose 6.

TOTP vs Push-based 2FA, WebAuthn, and SMS

TOTP is the middle ground: more secure than SMS (no SS7 interception, no SIM swap), simpler than WebAuthn, more portable than push (works offline). The downside relative to WebAuthn: the base32 secret exposes in plaintext if the server is breached, and TOTP is phishable - the code is typed into an attacker-controlled site just like the password. WebAuthn (FIDO2/passkeys) uses asymmetric crypto and includes the origin domain in the signed challenge, defeating phishing. Ladder from weakest to strongest: SMS OTP (NIST SP 800-63B deprecated for federal use), TOTP, Push 2FA, WebAuthn. For new deployments, offer WebAuthn first and TOTP as recovery; never SMS-only.

Frequently Asked Questions

Why does the code differ from my phone's authenticator app?

Three common causes: clock drift on one of the devices (TOTP is time-based; more than 30 seconds off from UTC produces wrong codes), different secret (double-check the base32 you pasted matches what is in the app), or non-default parameters (some services use 8 digits or SHA-256 instead of the RFC 6238 defaults this tool implements). Sync your system clock to NTP, re-enter the secret, and confirm the service uses 6-digit SHA-1 30-second TOTP. If all three match and codes still differ, the issue is almost certainly clock drift - a difference of 45 seconds produces a different 30-second window and therefore a completely different code.

Is my base32 secret stored or sent anywhere?

No. The secret lives only in the component's useState hook and is decoded locally via a JavaScript base32 routine. HMAC-SHA-1 runs in the browser's native crypto library via crypto.subtle.sign. There is no localStorage persistence, no IndexedDB, no fetch, and no telemetry event containing the secret. The tool works offline after the initial page load. If you want per-tab persistence, copy the secret to a password manager; refreshing the page clears it.

Is this suitable as a daily driver for my real 2FA accounts?

Not ideal. Dedicated authenticator apps (Google Authenticator, Authy, 1Password, Bitwarden, Aegis, Raivo) store the secret in encrypted local storage with biometric unlock, back it up to cloud with end-to-end encryption, and support features this tool does not (multiple accounts, QR scan, encrypted export). This tool is best for testing, one-off code generation, and debugging. For production 2FA, pair a hardware-backed authenticator (Aegis on Android with encrypted database, iOS Keychain-backed, or a YubiKey) with a recovery code printout.

Does this work with Microsoft Authenticator, Authy, and 1Password?

Yes. All three implement standard RFC 6238 TOTP with 6 digits, 30-second window, SHA-1 - exactly what this tool produces. If you paste the base32 secret from a Microsoft Authenticator export or 1Password one-time-password field, the codes match. Some services now offer proprietary push-based 2FA that is not TOTP-based; those cannot be generated here.

Can I generate HOTP codes (counter-based) with this tool?

No. This tool implements TOTP (RFC 6238, time-based) only. HOTP (RFC 4226, counter-based) uses the same HMAC-SHA-1 truncation but with an incrementing counter instead of a time window. HOTP is used by YubiKey OATH-HOTP mode and a few legacy SSH setups; most consumer 2FA moved to TOTP.

Is HMAC-SHA-1 still safe for TOTP given SHA-1 collision attacks?

Yes. SHA-1 collisions (SHAttered 2017) break collision resistance but not the pseudo-random-function property HMAC needs. HMAC-SHA-1 is still a secure MAC and remains FIPS-approved for authentication. RFC 6238 allows SHA-256 and SHA-512 variants but the installed authenticator app base defaults to SHA-1 for interoperability. The 20-bit output truncation is the real security parameter, not the underlying hash choice.

What happens if the attacker has my base32 secret?

They can generate valid 2FA codes forever until you rotate the secret server-side (disable and re-enable 2FA on the service). This is why TOTP is only a second factor, not a password replacement - a secret leak is recoverable if you still have the password, and a password leak is recoverable if you still have the TOTP. Both leaking simultaneously is game over. Store the base32 in a password manager with at-rest encryption, not in plaintext in a notes app or a screenshot gallery.

How accurate does my system clock need to be?

Within 30 seconds of UTC in the worst case; within a few seconds in practice. Most servers accept the previous, current, and next windows (a 90-second total tolerance). If your clock is more than 30 seconds fast or slow, some services will reject the code. Modern operating systems auto-sync via NTP by default; if you manually disabled time sync or your motherboard battery is dead, codes will fail intermittently. Run ntpdate or your OS equivalent to resync.

More Security & Privacy