Loading TOTP Code Generator…
Enter the secret an app was enrolled with and the digits it should be showing right now appear here.
The secret is the whole second factor. Anything holding it can produce these digits forever, which is why an authenticator app keeps it and never shows it again after enrolment. Pasting a live secret here is safe only in the sense that nothing on this page leaves your browser: the codes are computed by crypto.subtle on this machine and no request is made. Use this to check an enrolment, then treat the secret as used up if it has been anywhere it should not have been.
A code that matches here is evidence about the algorithm, not about the server. A service that rejects it may be enrolled with a different secret, may use a different period, or may have refused the previous step for its own reasons — and a service that accepts a code from four steps ago has a drift window far wider than RFC 6238 suggests, which is worth knowing on its own.
A time-based one-time password is arithmetic, not magic. RFC 6238 takes the current Unix time, divides it by a step of 30 seconds and throws away the remainder, giving a counter both ends can work out independently. That counter is signed with HMAC-SHA1 under the shared secret, four bytes are selected from the result by the dynamic truncation rule in RFC 4226, and the remainder modulo one million is padded to six digits.
Nothing is transmitted at any point, which is the property that makes the scheme work offline. Your phone and the server never speak to each other; they simply agree on the time and hold the same secret, and this page does the identical sum in your browser using the implementation that guards this site’s own admin login.
The moment to check a setup is while you still have another way in. Paste the secret shown at enrolment — or the whole otpauth:// URI behind the QR code, which avoids retyping thirty-two characters — and compare what appears here with what the app on your phone is showing. Matching digits mean the secret was transferred correctly and the two clocks agree.
The window of three codes shows why a mismatch is not automatically a failure. Verifiers commonly accept the step either side of the current one, so a code can be a little stale and still be taken. If the code you typed belongs to a neighbouring step, this page says which one and how many seconds out it was, which turns a vague failure into a clock problem you can fix.
Four things vary between implementations and any of them will produce codes that look plausible and are wrong: the step length, the number of digits, the hash, and the secret itself. Most services use 30 seconds, six digits and SHA-1, and every mainstream authenticator assumes that combination regardless of what the enrolment URI requests.
This tool produces the SHA-1 variant only, and says so rather than guessing when an otpauth URI asks for SHA-256 or SHA-512. That refusal is deliberate: silently showing the wrong digits would send somebody off to re-enrol an authenticator that was working perfectly.
Device clock drift is the other regular cause. A phone whose time is set by hand slips a few seconds a month, and once it drifts past the window a server allows, every code it produces is rejected. Turning on automatic time is the whole fix.
Everything that protects the scheme is in that base32 string. Anything holding it can generate valid codes indefinitely, which is why an authenticator shows the secret once at enrolment and never again, and why a screenshot of a QR code sitting in a photo library is a credential rather than a picture.
RFC 4226 requires at least 128 bits of shared secret and recommends 160, which is the twenty bytes most enrolment screens encode as thirty-two base32 characters. This page computes locally and sends nothing anywhere, but a secret that has been pasted into any tool has been somewhere it was not meant to be — re-enrol rather than assume.
Usually the account was enrolled with a different secret than the one you pasted, or the service uses a period or digit count other than the default. Check the enrolment URI parameters, and try the code immediately rather than at the end of a step.
No, and it is not built to. A browser tab keeps nothing, offers no device lock, and every visit means handling the secret again. Use it to verify an enrolment or to recover from one, then go back to a proper app.
That is the verifier’s choice, not the standard’s. Accepting one step either side is common, which tolerates roughly a minute of drift in total. Some services allow more, and a service that accepts a code several minutes old has a wider window than it probably intended.
Base32 uses the letters A to Z and the digits 2 to 7 exactly so that no character can be confused with another when read aloud or copied by hand. A zero would be indistinguishable from the letter O on most screens.