🔐 2FA TOTP QR Generator

🔧 OTP type

TOTP is what Google Authenticator and Authy use. HOTP is for hardware tokens with a counter (YubiKey OATH-HOTP, etc.).

🧾 Identity

🔑 Shared secret (base32)

Uses crypto.getRandomValues. Default 160 bits (RFC 6238 §5.1) for SHA1, 256 bits for SHA-256, 512 bits for SHA-512.

🧮 Algorithm

SHA1 = universal. Google Authenticator ignores this field and always uses SHA1.

📏 Code shape

15s 30s (default) 120s

🔎 Inspect existing otpauth:// URI

⚠️ {{ parseError }}
type: {{ parsedResult.type }}
issuer: {{ parsedResult.issuer || '—' }}
account: {{ parsedResult.account }}
secret: {{ parsedResult.secret }}
algorithm: {{ parsedResult.algorithm }}
digits: {{ parsedResult.digits }}
period: {{ parsedResult.period }}
counter: {{ parsedResult.counter }}

📱 Scan this QR with your authenticator

Fill in issuer, account, and secret to render a QR code.

📤 otpauth:// URI

{{ builtUri || '—' }}

🕒 Live preview (refreshes every {{ period }} s)

{{ liveCode || '------' }}
Next refresh in {{ secondsRemaining }} s
⚠️ {{ liveCodeError }}

⚠️ Compatibility warnings

  • {{ w }}

🛡️ Save the secret

Copy the base32 secret into your password manager before sharing the QR. Losing it means re-enrolling MFA on whichever service issued it.

⚠️

ℹ️ About 2FA TOTP QR Generator

What this tool does

Builds an otpauth:// Key URI and a matching QR code that any standards-compliant authenticator app — Google Authenticator, Authy, 1Password, Microsoft Authenticator, Bitwarden, FreeOTP, Aegis, Raivo — can scan to enroll a second factor. The same URI format also encodes HOTP (counter-based) tokens for hardware-style use cases.

The tool runs entirely in your browser. Your secret never crosses the network during interactive use — URI assembly, base32 encoding, QR rendering, and the live preview code are all computed locally with WebCrypto HMAC.

The otpauth:// Key URI Format

Authenticator apps consume URIs that look like this:

otpauth://totp/Acme%20Corp:alice%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=Acme%20Corp&algorithm=SHA1&digits=6&period=30
  • otpauth://totp/ — scheme + type (use hotp for counter-based).
  • Acme%20Corp:alice%40example.com — label as Issuer:Account, percent-encoded.
  • secret=… — required base32-encoded shared secret (RFC 4648 §6 alphabet: A-Z and 2-7).
  • issuer=… — recommended; redundant with the label but disambiguates collisions.
  • algorithm=SHA1|SHA256|SHA512 — HMAC family. SHA1 is the de-facto default.
  • digits=6|7|8 — code length. 6 is universal; 7-8 may not display in all apps.
  • period=30 (TOTP) — refresh interval in seconds. 30 is universal.
  • counter=N (HOTP only) — initial counter value.

How TOTP works (RFC 6238)

TOTP derives a short numeric code from a long shared secret plus the current time. The algorithm is:

  1. Take the current Unix time in seconds and divide by period (usually 30) — the quotient is the moving factor.
  2. Encode the moving factor as an 8-byte big-endian integer.
  3. HMAC the 8 bytes with the shared secret (RFC 4226 dynamic truncation).
  4. Take the resulting integer modulo 10^digits; zero-pad to digits characters.

Because the moving factor only changes every period seconds, both server and client converge on the same code as long as their clocks agree within a few seconds. Most servers accept the previous, current, and next period codes to absorb small clock drift.

Security ratings and recommendations

  • HMAC-SHA1 (RFC 6238 default) — Secure for TOTP use. The cryptographic weaknesses of SHA-1 (collision attacks against the hash function) do not apply to HMAC-SHA1; HMAC's security depends on PRF properties, which SHA-1 retains. NIST SP 800-107 explicitly permits HMAC-SHA1 for symmetric authentication. Use this for maximum compatibility — Google Authenticator ignores the algorithm parameter and always uses SHA1.
  • HMAC-SHA256 / HMAC-SHA512 — Stronger but less portable. Better future-proofing if your authenticator app and validating server both support them (Authy, 1Password, Aegis, FreeOTP all do; Google Authenticator does not).
  • Secret length — RFC 6238 §5.1 recommends a shared secret of at least 128 bits and strongly recommends 160 bits for HMAC-SHA1, 256 bits for SHA-256, and 512 bits for SHA-512. This tool generates 160-bit secrets by default.
  • Code length — 6-digit codes give 106 = 1 million possible values. Server-side rate-limiting on failed verifications is required (RFC 6238 §5.2). Without rate-limiting, a 6-digit code is easily brute-forceable.
  • Replay protection — RFC 6238 §5.2 requires that a code be accepted at most once per time-step. Servers must reject the previous-time-step code if it has already been used.
  • Clock skew — both sides need a clock within ±1 time-step (~30s) of UTC. Devices with NTP synchronisation are reliable; air-gapped offline devices may drift.
  • Phishing — TOTP does not protect against real-time phishing proxies (an attacker who relays the code to the legitimate site within the 30-second window). For phishing resistance, use WebAuthn / FIDO2 (passkeys) instead.

Common use cases

  • Enrolling 2FA for a user account: build the URI server-side, render the QR, ask the user to scan it. Save the base32 secret in your DB encrypted at rest.
  • Re-issuing a backup QR for users who lost their phone but have a recovery code, without rotating the secret.
  • Manual entry fallback: provide both the QR and the raw base32 secret so users on devices without a camera can type the secret in by hand.
  • Inspecting an existing otpauth URI shared from a password manager, to verify it carries the expected issuer/algorithm/digits/period.
  • HOTP setup for hardware tokens (YubiKey OATH-HOTP slot, Feitian, etc.) that use a counter rather than a clock.

Source references

  • RFC 6238 — TOTP: Time-Based One-Time Password Algorithm (May 2011).
  • RFC 4226 — HOTP: An HMAC-Based One-Time Password Algorithm (December 2005).
  • RFC 4648 — The Base16, Base32, and Base64 Data Encodings (October 2006).
  • Google Authenticator Key URI Format — the de-facto spec for the otpauth:// scheme used by every modern authenticator.
  • RFC 2104 — HMAC: Keyed-Hashing for Message Authentication.

Limits and practical notes

  • Your secret is processed entirely in your browser. Nothing leaves your machine during interactive use. The API endpoint exists for server-side enrollment flows.
  • The QR code is rendered as inline SVG with no external library — works fully offline.
  • Save the base32 secret in your password manager. Losing it means re-enrolling MFA on whichever service issued it.
  • Google Authenticator ignores the algorithm and digits URI parameters and always uses SHA1 / 6 digits. If you need non-default values, verify support in your target app first.
  • The shared algorithm runs in both Node and the browser via the Module-First TypeScript module backing this page.

API Usage Example:

POST /api/tools/security/totp-qr-generator
Content-Type: application/json

{
    "operation": "buildUri",
    "type": "totp",
    "issuer": "Acme Corp",
    "account": "[email protected]",
    "secret": "JBSWY3DPEHPK3PXP",
    "algorithm": "SHA1",
    "digits": 6,
    "period": 30
}
Ready