Tooleux

TOTP Generator

Generate TOTP 2FA codes from a base32 secret. Live countdown. Nothing leaves your browser.

Runs in your browser. Nothing leaves your device.
Generate TOTP codes from a base32 secret. RFC 6238. Live countdown, next code preview. Runs entirely in your browser. Read more Show less

What is TOTP?

TOTP (Time-based One-Time Password) is the algorithm behind nearly every 2FA app: Google Authenticator, Authy, 1Password, Microsoft Authenticator, Bitwarden. It generates a short numeric code - usually six digits - that changes every 30 seconds. When you are asked to enter "the code from your authenticator app", you are entering a TOTP value.

The algorithm is defined in RFC 6238. It is built on top of HOTP (RFC 4226), which uses a counter instead of the current time. TOTP's counter is floor(unix_time / 30) - so the counter increments once every 30 seconds, and the code changes at each step.

Both server and client share a secret, usually shown during account setup as a base32 string or a QR code. Neither side ever sends the secret over the network. The server and the client independently compute the same six-digit code from the secret and the current time.

How to use

Paste the base32 secret - the string labeled "setup key" or "manual entry" when you enable 2FA on a site. The tool shows the current code, a countdown bar showing time until the next code, and the next code one period ahead so you can pre-read.

Options:

  • Digits - 6 (default), 7, or 8. Most services use 6.
  • Period - seconds per code. 30 is universal; some services use 60.
  • Algorithm - SHA-1 (default, what nearly everything uses), SHA-256, SHA-512.
  • Counter - for HOTP mode. Only used if you switch to counter-based.

The code updates automatically every second. Nothing you enter is transmitted - the secret stays in the tab.

What this tool is not

It does not store your secret. If you close the tab, the secret is gone. There is no account, no sync, no history. That is intentional: a TOTP secret that is stored somewhere is a TOTP secret that can be stolen from that somewhere.

It is not a substitute for a proper authenticator app. Apps keep the secret encrypted at rest and can be backed up. This tool exists to (a) verify that a secret is working, (b) generate a code on a machine where you do not want to install another app, (c) debug a 2FA integration where the server and the client disagree about the algorithm or period.

A note on pasting TOTP secrets

A TOTP secret is a real secret. Anyone who has it can generate valid codes for the account it protects, indefinitely. Pasting it into any web page means trusting that page's code, the browser, and any installed extensions.

That said: for a security tool, "runs in your browser, no uploads" is exactly the property that makes this safe to use. This tool does not phone home, has no server-side component, and never writes your secret to disk. It is the same trust model as opening an authenticator app on your own machine, minus the persistent storage.

If you would not paste a secret into any web page under any circumstances, do not paste it here. Use oathtool on your own machine. The command is in the CLI section below.

Why is my code not matching?

The three parameters that most often differ between server and client:

  • Algorithm. Default is SHA-1. Some services use SHA-256 or SHA-512 without saying so clearly.
  • Digits. Default is 6. A few services use 8.
  • Period. Default is 30. Some use 60.

Also common: the secret you were shown includes spaces or hyphens for readability. This tool strips them. Some services pad the base32 string with =; this tool tolerates that too. If your code still does not match, verify the secret is complete and not truncated - a base32 secret that lost one character still decodes but produces a different code.

There is also clock skew. TOTP codes are valid for a window around the current time, typically one period in either direction. If your device clock is off by more than a minute, codes will be rejected. This tool uses your system clock, so if the code it generates does not work, check that your clock is accurate.

FAQ

Is TOTP the same as 2FA?

TOTP is one form of 2FA - the most common one. 2FA also includes hardware keys (FIDO/WebAuthn), SMS codes, and push notifications. TOTP is the "six-digit code from an app" flavor.

Can TOTP codes be replayed?

Within the same 30-second window, yes - a code is valid for the entire period it belongs to. Servers mitigate this by rejecting a code that has already been used (remembering the last accepted counter value). The one-time aspect of TOTP is enforced by the server, not by the code itself.

What if I lose the secret?

You cannot recover it. This is by design - there is nothing stored anywhere to recover from. Backup codes or a second registered device are the intended recovery path. If you registered only one TOTP device and lost it, account recovery depends on the provider's other methods.

Why does Google Authenticator use SHA-1?

Because the TOTP spec predates practical SHA-1 attacks, and because switching the default would break every server that expected SHA-1. SHA-1 is fine for this use case - the HMAC construction is not affected by the collision attacks that broke SHA-1 for signing.

Can I use this for HOTP (counter-based)?

Yes. Switch the mode to counter and enter the counter value. HOTP is used by some hardware tokens and a few legacy services, but TOTP has largely replaced it.

How long does a TOTP secret need to be?

RFC 4226 recommends a shared secret of at least 128 bits (16 bytes) and prefers 160 bits (20 bytes). In base32, that is 26 or 32 characters. Most services use 16 or 20 bytes. Shorter secrets are legal but weaken the security proportionally.

Command line equivalent
# oathtool (Debian/Ubuntu: apt install oathtool)
oathtool --totp -b JBSWY3DPEHPK3PXP

# With explicit algorithm and digits
oathtool --totp --algorithm SHA256 --digits 8 -b JBSWY3DPEHPK3PXP

# Python
pip install pyotp
python3 -c 'import pyotp; print(pyotp.TOTP("JBSWY3DPEHPK3PXP").now())'

# Node
npm i otpauth
node -e 'const {TOTP} = require("otpauth"); console.log(new TOTP({secret:"JBSWY3DPEHPK3PXP"}).generate())'

# HOTP instead of TOTP
python3 -c 'import pyotp; print(pyotp.HOTP("JBSWY3DPEHPK3PXP").at(0))'
oathtool -b --counter=0 JBSWY3DPEHPK3PXP
Loads a test value into the form
Secret (base32)
Full output