🔐 TOTP Secret Generator
Generates a random Base32-encoded secret key in the format authenticator apps (Google
Authenticator, Authy, 1Password, etc.) expect for TOTP-based two-factor authentication, along
with the matching otpauth:// setup URI. This is a standalone generator for
testing or self-hosted setups — it does not connect to any account.
The secret, and what the app does with it
Each character is drawn with rejection sampling from the 32-symbol RFC 4648 Base32 alphabet (A-Z and 2-7), so every character carries exactly five bits. The authenticator then folds that key into the RFC 6238 code:
bits = characters x 5 26 chars -> 130 bits
T = floor(unix_time / 30)
code = truncate(HMAC-SHA1(key, T)) mod 10^6
The otpauth:// URI spells out those defaults -
algorithm=SHA1, digits=6, period=30 -
because they are the only combination every authenticator app reliably
supports.
Choosing a length
- 16 characters decodes to exactly 10 bytes, the RFC 4226 minimum and what Google issues.
- 32 characters is 20 bytes, matching the SHA-1 output length, which is the size RFC 4226 actually recommends.
- The issuer and account name are labels only - URL-encoded into the URI so your app can show which account a code belongs to. They add nothing to the key.
Frequently asked questions
Can I use this secret to turn on 2FA for my Gmail or bank?
No. Those services generate their own secret and store their copy when you enrol. This generator is for the other side of the exchange - a self-hosted app or a test setup where you are the one issuing the key.
Why does the URI say SHA1 when SHA-1 is broken for signatures?
TOTP uses it inside HMAC, where the collision attacks that killed SHA-1 for certificates do not apply. HMAC-SHA1 remains sound and is what almost every authenticator implements.
What happens if someone sees my TOTP secret?
They can generate valid codes indefinitely, exactly as if they held the phone. The secret is a permanent shared key, not a one-time value, so a leaked one has to be replaced and the account re-enrolled.