Stillcode › Two-factor authentication › How the codes work

How authenticator codes work

Six digits, changing every thirty seconds, computed on your own device. Understanding where they come from is what makes the rest of this obvious — including the part nobody warns you about.

The secret is handed over once

When a service offers you a QR code to scan, that image is a short string — the shared secret. Your authenticator stores it. The service stores its own copy. From that moment on, neither side sends anything to the other: both hold the same secret, both know the time, and both compute the same six digits from those two things.

The standard is RFC 6238, TOTP — a Time-based One-Time Password. The code is a truncation of an HMAC over the secret and the current thirty-second interval. Nothing about producing it requires a network.

Diagram of how a TOTP authenticator code is made. Step one: the service shows a shared secret once, as a QR code, and the phone stores its own copy. Step two: at sign-in the service and the phone each combine that secret with the clock and reach the same six digits separately, with nothing passing between them.
RFC 6238 in two steps. The arrow only ever points one way, and only once.

Why it changes every thirty seconds

The interval is an input to the calculation, so the answer changes when the interval does. That is what limits the damage if a code is seen or intercepted: it is worth something for at most thirty seconds, and only once.

It also explains the only common failure that is not about a lost phone: if your device's clock is wrong, the codes are wrong. The maths uses the clock, so a drifted clock computes the interval before or after the one the server is on. Set the phone's time to update automatically and the whole class disappears.

⛔ Why nobody can send you a replacement

The service can verify your code. It cannot give your secret back to you in any way that is useful, because the security of the whole scheme rests on that secret having been transmitted exactly once, at setup.

So the codes are not "in your account". They are on whatever device you scanned that QR code with, and nowhere else unless you deliberately put them somewhere else.

That is the property that makes an authenticator stronger than a texted code — and the same property is why a lost phone is a different kind of problem here than it is for anything else on your device.

Recovery codes are the escape hatch, and they are the whole escape hatch

Almost every service hands you a list of one-time recovery codes at setup, usually on the screen immediately after the QR code, usually the screen people click past. Each one substitutes for a six-digit code exactly once.

They are not a backup of your secret and they do not restore your authenticator. They are a way back into the account, from which you can set a new authenticator up. That is enough, and nothing else is.

⚠️ Generating a fresh set invalidates the old set. That is the right move when you cannot find the old one — but do it from a device that is already signed in.

What the QR code is not

It is worth saying plainly, because it drives a lot of bad advice: a screenshot of the QR code is a copy of the secret. Anyone who has that image can generate your codes indefinitely, until you rotate the secret. It is not a backup to keep in a photo library that syncs somewhere.

Where Stillcode fits

Stillcode implements RFC 6238 on iPhone, iPad and Mac and makes no network calls at all — codes are computed on the device from a secret held in the iOS Keychain. Unlimited accounts, bulk import, search, the Face ID lock and the per-account migration QR are free; iCloud Keychain sync, the encrypted export file and restoring from one are Stillcode Pro. Get it on the App Store

The seven second factors, and what each one costs you

These are the seven the directory tracks, and the seven the table on every service page uses. ⭐ Written out once, here, rather than fifty times — the answer does not change with the service, only which of them that service accepts:

MethodWhat it is
Authenticator app (TOTP)A six-digit code generated on your own device from a shared secret, following RFC 6238. Nothing is sent over the network to produce it.
Hardware security keyA physical key you tap. The strongest of the options here, and the only one that resists a convincing phishing page.
The service’s own appA push prompt or code from software this service publishes itself. It works, and it only works here.
The service’s own deviceA dedicated token issued by the service. Usually posted to you, and usually replaceable only by them.
SMS text messageA code texted to your number. The weakest of the common options: it depends on your mobile carrier, and a SIM swap defeats it.
Voice callA code read out over a phone call. Same dependency on the carrier as SMS, and the same weakness.
EmailA code sent to your mailbox — which makes the account only as protected as the mailbox is.
The seven second factors ordered by how far a working code travels. An authenticator app and a hardware security key never leave your hands; the service’s own app and its own device depend on the service; below a dividing line marked "somebody else is part of the lock" sit SMS, a voice call and email, which pass through a mobile carrier or a mailbox.
The same seven, in the same order, as the table on every service page.

⭐ The ordering is not alphabetical and is not accidental: it runs from the factor that never travels to the one that travels furthest. Anything above the line that a carrier or a mailbox can reach is a factor somebody else's security is holding up.

Where an authenticator app is the only option

Fifteen of the fifty services here offer no SMS and no voice call as a second factor. On those accounts a generated code is not an upgrade over a texted one — it is the only thing on offer, so everything above applies directly:

Amazon Web Services Asana Bitbucket Canva Cloudflare GitLab Heroku Kraken Namecheap Netlify Nintendo Account PayPal Proton Reddit Roblox

The full set, with what each one accepts: all fifty services.