Free · Private · Client-side

TOTP Secret Key Generator

Generate Base32-encoded secrets for Time-based One-Time Password (TOTP) authentication. Compatible with Google Authenticator, Authy, Microsoft Authenticator, and other 2FA apps.

Generated values never leave this device.
Estimated entropy: 160 bits · Base32 (RFC 4648) · 20 random bytes~1.7 quintillion times the age of the universe to crack
Weak · <50 bitsFairGood · 70+Strong · 100+

In plain terms: a gaming PC guessing a million passwords per second would need 1,677,978 quintillion times the age of the universe. Even someone renting every cloud server on Earth — a trillion guesses per second — would need 1.7 quintillion times the age of the universe. Nobody is guessing this password; the only realistic risks are it being reused or phished.

Generated secrets

Strong160 bits
Strong160 bits
Strong160 bits
Strong160 bits
Strong160 bits

OTPAuth URI (for QR Codes)

Generate a secret first

Use this URI to generate a QR code that users can scan with their authenticator app.

Implementation Examples

Python (pyotp)
import pyotp

# Store this secret securely for each user
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")
Node.js (otplib)
const { authenticator } = require('otplib');

const secret = "JBSWY3DPEHPK3PXP";

// Generate current code
const token = authenticator.generate(secret);

// Verify user's code
const isValid = authenticator.verify({ token: userCode, secret });
PHP (sonata-project/GoogleAuthenticator)
use Sonata\GoogleAuthenticator\GoogleAuthenticator;

$ga = new GoogleAuthenticator();
$secret = "JBSWY3DPEHPK3PXP";

// Verify user's code
$isValid = $ga->checkCode($secret, $userCode);

How TOTP Works

TOTP generates a 6-digit code that changes every 30 seconds. Both the server and the user's authenticator app share the same secret key, allowing them to generate matching codes without network communication.

  • Based on HMAC-SHA1 algorithm (RFC 6238)
  • Uses Unix timestamp divided by 30-second intervals
  • Base32 encoding makes secrets easy to type manually

Bulk Generation

secrets

Generate in Terminal

Python

$python3 -c "import base64, secrets; print(base64.b32encode(secrets.token_bytes(20)).decode())"

OpenSSL + base32

$openssl rand -hex 20 | xxd -r -p | base32

Node.js (URL-safe variant)

$node -e "console.log(require('crypto').randomBytes(20).toString('base64').replace(/[+/=]/g, c => ({'+':'-','/':'_','=':''}[c])))"