TOTP 2FA QR Codes Explained

A technical deep-dive into the otpauth:// URI format, base32 secrets, and RFC 6238 TOTP math.

本文目前仅提供英文版本。

What is TOTP

TOTP (Time-based One-Time Password, RFC 6238) is the algorithm behind Google Authenticator, Authy, 1Password, Bitwarden, and every other authenticator app. It produces a 6-digit code that changes every 30 seconds based on a shared secret and the current Unix time.

The otpauth URI

otpauth://totp/Issuer:account@example.com?secret=BASE32SECRET&issuer=Issuer&algorithm=SHA1&digits=6&period=30

The URI scheme is otpauth://, the type is totp (the other option is hotp, counter-based), then the label, then query parameters. Authenticator apps parse this URI and add it to the user's vault with one scan.

The label

Optional format: Issuer:account@example.com. The Issuer prefix is redundant with the issuer query param but most apps respect both.

The secret

A base32-encoded byte string (A-Z and 2-7, no padding). At least 128 bits recommended — most servers use 160 bits (32 base32 chars). Never URL-encode the secret; leave it as raw base32.

Algorithm, digits, period

algorithm: SHA1 (default, universally supported), SHA256, or SHA512. digits: 6 (default) or 8. period: 30 seconds (default) or 60. Stick with defaults unless you have a reason — some authenticator apps don't implement the non-default options.

How the code is computed

At each 30-second interval, the authenticator does: HMAC-SHA1(secret, floor(unix_time / 30)), takes the last 4 bits of the HMAC as a dynamic offset, reads 4 bytes starting at that offset, masks to 31 bits, and modulo-reduces by 106 to get a 6-digit code.

Use Abundera QR to generate one

Open the TOTP generator, fill in issuer (your brand name), account (the user's email or username), and a base32 secret. Defaults for algorithm/digits/period are correct for nearly every server. Download the PNG and email or SMS it to the user — or embed it in your enrollment flow.

Privacy note

Your TOTP secret is a shared credential between the server and the user. Abundera QR never sees either. All encoding happens in the browser. Read the full privacy policy.