Generate a TOTP Secret — Free Random Base32 Key Generator
Need a fresh secret to set up two-factor authentication? The TOTP Secret Generator creates a random Base32-encoded secret at your chosen secret strength — 80-bit, 128-bit, or 160-bit — ready to type or scan into any authenticator app. Every character comes from your browser's Web Crypto API, so the secret is generated and shown only on your own device.
Every time you add two-factor authentication to an application, the first decision you make — and the most security-critical one — is how to produce a strong, unpredictable TOTP secret generator output that your server and your users' authenticator apps can share. Get that shared seed wrong and the entire chain of login security falls apart. This page gives you a free, browser-based, client-side totp secret generator that keeps all values on your device, plus everything you need to wire the result into real code, QR codes, and enterprise provisioning workflows.
How the TOTP Secret Generator Creates a Cryptographically Strong Seed
How a TOTP Secret Works Under the Hood
A time-based password (TOTP) is defined in RFC 6238 and builds on the HMAC-based specification for a one time password. At runtime, both the server and the verification app independently compute an HMAC-SHA1 digest over the concatenation of the shared credential and the current Unix timestamp divided by the configured period (typically 30 seconds). The last four bytes of that digest are truncated into a 6-digit code that refreshes every time the floor of unix_timestamp / period changes — updating in seconds and never repeating. No network communication occurs after the initial provisioning step; the magic is that both sides hold the same seed and the same clock.
The formula that drives every TOTP time-based password is:
$$T = \left\lfloor \frac{t - t_0}{X} \right\rfloor$$where t is the current Unix timestamp, t₀ is the Unix epoch (0), and X is the time step in seconds (default 30). The one-time password is then:
$$\text{OTP} = \text{Truncate}\bigl(\text{HMAC-SHA1}(K,\, T)\bigr) \bmod 10^{d}$$where K is the secret key and d is the number of digits (default 6).
Seed and Private Key Explained
The generator outputs a base32-encoded string — specifically, a base32 seed produced by encoding 20 random bytes (160 bits) according to RFC 4648. Those 20 bytes constitute the private key, also called the seed or shared secret. The estimated entropy of a 160-bit value is so vast that even a cloud server attack running a trillion guesses per second would require 1.7 quintillion times the age of the universe to exhaust the keyspace — making brute force irrelevant. The only realistic threats are a phishing attack that steals the seed or a reused secret, not a gaming PC attack. Base32 encoding is chosen over raw hex because it uses only uppercase letters and digits 2–7, making a manually typed secret far less error-prone. The generator also shows a hex seed representation alongside the base32 output so you can cross-reference both formats during provisioning, with secure storage of the result being your responsibility once copied.
Privacy note: All computation is client-side and locally computed. Generated values never leave this device and no seed is ever sent to a server. This is a browser-based generator — your secrets stay private.Generate Secrets with the TOTP Toolset — Browser, Terminal, and URL Parameters
Browser-Based Generation
The totp in browser generator above is an open source browser tool and developer tool that runs entirely in your browser with no server-side component. Click Generate to produce a new cryptographically random secret instantly. You can adjust the key-length slider to control how many random bytes of randomness underpin the output — the default of 20 bytes yields 160 bits of entropy, which is the recommended minimum per RFC 6238. The tool exposes the result both as a base32-encoded secrets string (ready to paste into any compatible app) and as a raw hex string for systems that prefer binary input.
Generate via Terminal — Code Generation Without a UI
Terminal generation is the fastest route to a fresh secret when you are scripting provisioning pipelines or running in a headless environment. Three one-liners cover the most common runtimes:
Python — uses secrets.token_bytes for cryptographically secure random bytes:
python3 -c "import base64, secrets; print(base64.b32encode(secrets.token_bytes(20)).decode())"OpenSSL + base32 — pipe openssl rand through xxd to convert hex to binary, then encode:
openssl rand -hex 20 | xxd -r -p | base32Node.js — uses crypto randomBytes and produces a url-safe variant of the base64 output (swap characters for environments that cannot handle standard base64):
node -e "console.log(require('crypto').randomBytes(20).toString('base64').replace(/[+/=]/g, c => ({'+':'-','/':'_','=':''}[c])))"Passing Parameters in the URL — Additional Parameters for Automation
Providing parameters via URL lets you pre-configure the generator for your stack. Append any combination of the following as query parameters — useful when linking colleagues directly to a configuration or embedding the tool in internal documentation. These parameters in url control every aspect of the generated TOTP output:
| Name | Default | Description |
|---|---|---|
key | random | Pre-fill the private key input field with a specific base32 secret (acts as a totp secret override). |
digits | 6 | Number of digits in the generated code — typically 6 or 8. |
period | 30 | Validity window in seconds. The default 30 seconds / 30-second intervals matches most authenticator app defaults. |
algorithm | SHA-1 | HMAC algorithm — SHA-1 (most compatible) or SHA-256 (stronger, supported by physical security keys and some enterprise MFA providers). |
Example URL combining all url parameters:
https://example.com/totp?digits=6&period=60&algorithm=SHA256&key=JBSWY3DPEHPK3PXPFor bulk generation — provisioning multiple users at once — loop the Python or OpenSSL one-liner in a shell script, writing each generated secret alongside the corresponding user email or UPN into a staging file before importing into your identity platform:
for i in $(seq 1 100); do
SECRET=$(python3 -c "import base64, secrets; print(base64.b32encode(secrets.token_bytes(20)).decode())")
echo "user${i}@example.com,${SECRET}"
done > secrets.csvUsing Your TOTP QR Image Decoder Output in Apps and Code
Building an OTPAuth URI for QR Code Scanning
Once you have a secret, the standard way to deliver it to users is via qr code import scanning. Apps like Google Authenticator, Authy, and Microsoft Authenticator all understand the otpauth:// URI scheme. To generate QR code assets, construct the otpauth URI in this format and pass it to any QR-rendering library:
otpauth://totp/{provider}:{user}?secret={SECRET}&issuer={provider}&algorithm=SHA1&digits=6&period=30The provider field names your application (e.g., MyApp); the user field is usually the user's email address. To generate QR and allow users to scan authenticator apps, pipe this URI into a library such as qrcode (Python) or qrcode.js (browser). The tool on this page handles this step for you — fill in the service name and user identifier, click Generate URI, and you get a ready-made import QR codes-compatible image. You can also use the built-in totp qr image decoder tab to verify that an existing QR image encodes the secret you expect — useful for auditing physical security keys before distribution.
To import QR codes into the tool, use the decoder tab, which parses the otpauth:// payload from any scanned image without sending the image or the embedded seed anywhere — values never leave device at any point during decoding.
Code Examples by Language — Implementation Examples
The following implementation examples show how to generate TOTP code and verify code in the three most common server-side runtimes. Each snippet uses the same demonstration secret; replace it with your securely stored value in production.
Node.js implementation using the otplib library:
const { authenticator } = require('otplib');
// Secret stored securely server-side (never log this)
const secret = "JBSWY3DPEHPK3PXP";
// Generate current TOTP code
const code = authenticator.generate(secret);
console.log(code); // e.g., "492039" — a fresh 6-digit code
// Verify user-submitted code (accounts for time drift automatically)
const isValid = authenticator.verify({ token: userCode, secret });
console.log(isValid); // true or falsePython implementation using the pyotp package:
import pyotp
# Store this secret securely for each user — never commit to source control
secret = "JBSWY3DPEHPK3PXP"
# Generate current TOTP code
totp = pyotp.TOTP(secret)
print(totp.now()) # e.g., "492039"
# Verify a code from user
is_valid = totp.verify("492039")
print(is_valid) # True
# Build a provisioning URI for QR code generation
uri = totp.provisioning_uri(name="[email protected]", issuer_name="MyApp")
print(uri) # otpauth://totp/MyApp:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=MyAppPHP implementation using GoogleAuthenticator (via sonata-project/google-authenticator):
use Sonata\GoogleAuthenticator\GoogleAuthenticator;
$ga = new GoogleAuthenticator();
$secret = "JBSWY3DPEHPK3PXP";
// Verify user's submitted code
$isValid = $ga->checkCode($secret, $userCode);
var_dump($isValid); // bool(true)Each library handles time drift and offset tolerance internally, accepting codes from the immediately preceding and following 30-second intervals to compensate for clock skew between client and server.
| Language | Package | Install Command |
|---|---|---|
| Node.js | otplib | npm install otplib |
| Python | pyotp | pip install pyotp |
| PHP | sonata-project/google-authenticator | composer require sonata-project/google-authenticator |
Importing Hardware Token Files for Entra ID — 2FA at Enterprise Scale
If your organisation deploys physical hardware tokens rather than (or alongside) phone-based multi-factor verification, this totp toolset supports a direct device-import workflow via the Entra ID hardware-key import format. After generating a batch of secrets, use the CSV export or JSON export button to produce an import file with the required columns — UPN, serial, secret (base32), algorithm, digits, and period — that maps directly to the Microsoft identity platform bulk upload schema. The seed export is performed entirely in the browser, so no secrets touch a remote server during the csv export or json export steps. This approach is ideal for enterprise multi-factor rollouts where physical keys must be pre-provisioned and assigned to specific user profiles before distribution, supporting login hardening at scale.
Keeping TOTP Secrets Safe — Verify TOTP Codes and Protect Your Keys
Storage and Transmission Best Practices for Shared Secrets
A TOTP secret is the root of trust for every verification session it covers. Treat it with the same care as a passphrase or private certificate — arguably more, because it cannot be rotated without re-enrolling the user. The following practices form the baseline for responsible secret handling and profile security:
- Encrypt at rest: use encryption (AES-256 or equivalent) for secure storage of secrets in your database. Never write a plaintext secret to disk or a log file — server-side logging of raw seeds is a common and serious mistake.
- HTTPS only: transmit the secret to the end user exactly once during provisioning, over a TLS-protected channel. There is no legitimate reason to display the secret again after initial enrolment.
- No reuse: generate a fresh, unique credential for every user and every service. A reused seed across profiles undermines identity isolation and makes lateral movement trivial for an attacker.
- Rotate on compromise: if a secret is suspected of being exposed via phishing or other means, revoke and re-provision immediately. Unlike a static passphrase, code generation can continue indefinitely on the attacker's device once the seed is leaked.
- Limit key-length scope: generate secrets with the full recommended key length of 160 bits. Shorter seeds reduce the strength classification from strong toward weak — stay in the strong band to make both a gaming PC attack and a cloud server attack computationally impossible, requiring quintillion guesses to succeed.
For open source totp projects, contributors and maintainers should audit the repository to ensure secrets are never committed to version control. Check all releases for accidental exposure in configuration files, and review pull requests carefully — a single mistaken commit containing a live seed can invalidate an entire cohort of enrolled users and require mass re-provisioning. Responsible cryptography, disciplined app integration, and strong user verification workflows are what separate a robust two-factor system from a false sense of protection and multi-factor security.
Frequently Asked Questions
- What is a TOTP secret?
- A TOTP secret (also called a seed or shared key) is the random value an authenticator app and a service both store to generate matching time-based one-time codes. It's usually shown as a Base32 string (letters A-Z and digits 2-7) because that alphabet is easy to type and scan from a QR code without ambiguous characters.
- How long should my TOTP secret be?
- RFC 4226 (the HOTP specification TOTP builds on) recommends at least 128 bits, and specifically suggests 160 bits for HMAC-SHA1-based implementations. This tool defaults to 160-bit (32 Base32 characters), which matches what most services and authenticator apps generate. 80-bit (16 characters) is shorter and easier to type manually, but offers a smaller margin of safety.
- Is this secret compatible with Google Authenticator, Authy, and other apps?
- Yes. The Base32 output is the standard format every major authenticator app (Google Authenticator, Authy, Microsoft Authenticator, 1Password, Bitwarden) expects, either typed in manually or embedded in an otpauth:// QR code. Use the OTPAuth URI Builder or Two-Factor QR Code Generator to turn this secret into a scannable enrollment code.
- Does the secret get sent anywhere?
- No. This tool generates the secret entirely in your browser using the Web Crypto API's cryptographically secure random number generator. Nothing is transmitted, logged, or stored — reload the page and the secret is gone.
- Can I use this secret for both TOTP and HOTP?
- Yes — the secret itself is just random key material; whether it's used with a time counter (TOTP) or an event counter (HOTP) is decided when you build the otpauth:// URI or configure the service, not by anything encoded in the secret.