TOTP QR Code Generator
Build a SHA1 otpauth URI, QR image, and current test code
The secret is equivalent to a 2FA password. Use it only on a trusted device and never share the QR code.
About this tool
Create an otpauth://totp setup URI, a PNG QR image, and a current HMAC-SHA1 test code. Supply a Base32 secret or generate 20 random bytes (160 bits) with Web Crypto, then choose 6/8 digits and a 30/60-second period. The account label is required and issuer defaults to TOTP; neither label may contain a colon. The tool does not create or bind a server account. Secrets are not uploaded or saved as drafts, but the generated URI and QR image contain the complete secret.
Production Snippets
Inspect a public enrollment test URI
text
Issuer: ToolsKit Demo
Account: [email protected]
Secret: JBSWY3DPEHPK3PXP (public demo only)
Digits: 6; Period: 30
otpauth://totp/ToolsKit%20Demo%3Ademo%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=ToolsKit+Demo&algorithm=SHA1&digits=6&period=30
Scanning stores the secret in the authenticator; it does not enroll an account on your server.Frequently Asked Questions
What does the QR image contain?
The complete otpauth://totp URI, including the Base32 secret, issuer/account label, SHA1 algorithm, digits, and period. The URI can be copied and the QR downloaded as PNG. Anyone who receives either artifact can derive codes from that secret.
Does scanning the QR code enable 2FA on my service?
No. It adds a seed to a compatible authenticator; the service must independently associate the same secret with the account and verify enrollment. This tool does not call a service API, create accounts, issue recovery codes, or enforce login policy.
How are random secrets generated?
Web Crypto generates 20 random bytes, encoded as 32 unpadded Base32 characters: 160 bits of random data. The example button uses a public shared secret for demonstration. Never use that example secret for real accounts.
Which secret and label inputs are accepted?
A complete Base32 byte encoding, with optional lowercase, whitespace, and correct terminal padding. Invalid lengths and unused bits are rejected. Account is required; blank issuer becomes TOTP. Colons are rejected in both fields because the label uses a colon to separate issuer and account.
Will every authenticator accept 8 digits or 60 seconds?
Not necessarily. This tool produces SHA1 with 6/8 digits and 30/60 seconds, but apps can ignore optional URI parameters or limit support. Compare the current test code on synchronized clocks in the actual app. The local code is a diagnostic, not server authentication.
Are setup secrets retained after I clear the page?
No localStorage draft is created. Editing or clearing invalidates pending QR and code generation; the timer stops when the page unmounts. A copied URI, downloaded PNG, or authenticator enrollment remains wherever you saved it and must be handled separately.
Keep browsing