OTP

A code that works only once. How it is generated, what separates an app code from one that arrives by SMS, and why that difference decides whether a SIM swapping attack takes over the account.

In short

An OTP is a single-use code a system asks for to confirm that whoever is on the other side has access to a given channel or device. It is valid for a single operation and for a short window, and that expiry is its whole point: a stolen code is worthless once it has been used.

It is the industry's most widespread second factor and the easiest to implement. It is also the one with the most variants, and the variants are not worth the same.

The code derives from a counter or a clock

There are two ways to produce a single-use code, and it is worth telling them apart from the start because they do not have the same properties.

Behind an algorithm-generated OTP, which is the case with HOTP and TOTP, there is a shared secret, the seed, that the server and the code generator keep separately. The code is calculated from that seed. What changes between the two standard algorithms is what else enters the calculation besides the secret.

  • HOTP — the code derives from a counter that advances every time a new one is generated, per RFC 4226. It does not expire by time: it stays valid until it is used or until the server resynchronizes the counter.
  • TOTP — the code derives from the clock, in fixed windows that are usually 30 seconds, per RFC 6238. It expires on its own, with no one having to use it.

Both share the same structural condition: a secret exists and lives in two places. Whoever obtains the seed can generate valid codes without ever touching the person's device.

In SMS OTP and email OTP there is no seed and nothing the person keeps. The server generates a random code on the spot and transmits it over a channel, and the entire weight of security shifts to that channel. That is the difference the next section explains.

The channel changes the security level, not the code

The six-digit code always looks the same. What changes is where it comes through, and that is where the real difference between implementations lies.

  • App OTP — the code is calculated on the device, with the seed stored locally. It never travels over any network. To intercept it you have to reach the device or the seed.
  • SMS OTP — the code is generated on the server and travels over the mobile network to the phone line. The factor is not tied to the device: it is tied to the number.
  • Email OTP — the factor inherits the security of the mailbox, which is usually protected with a password and, with luck, another factor.

An app OTP and an SMS OTP look identical to the user. For an attacker they are two different problems.

SMS OTP is the factor that SIM swapping breaks

SIM swapping consists of getting the carrier to reassign a line to a SIM the attacker controls. From that moment on, every message sent to that line reaches another phone, codes included.

What is uncomfortable about it is that nothing on the customer's side is compromised. The password stays secret, the phone stays in the owner's pocket, and the authentication system works exactly as designed. The factor was delivered to the correct line. The line changed owners.

A second limit reaches every OTP, not just SMS ones: the code can be typed in the wrong place. In a phishing or smishing attack with real-time relay, the attacker requests the code on their own site and uses it against the real system within the validity window. The code works because it is legitimate.

A factor the person can read and repeat is a factor they can repeat to whoever should not have it.

Where it is worth replacing, and where it is not

OTP is not broken. It falls short of what a high-value operation demands, and it remains reasonable for many others.

  • Against credential theft, it is enough. A leaked password does not open the account if the second factor is missing. It is what stops a credential stuffing attack.
  • Against phishing with relay, it is not enough. No code that can be typed out resists that vector. What does resist is a credential bound to the origin, which is what FIDO2 and passkeys provide.
  • Against SIM swapping, the channel decides. Moving the OTP from SMS to an app removes the vector entirely without changing the user's mental model.

The design question is not whether to use OTP. It is which factor covers which operation, and that is an MFA decision.

Frequently asked questions

It is a single-use code a system asks for to confirm that whoever is trying to access it has control over a given device or channel. It is valid for a single operation and expires by time or by use. There are two ways to produce it: algorithm-generated OTPs, like HOTP and TOTP, are calculated from a secret shared between the server and the code generator; the ones that arrive by SMS or email are random codes the server generates and transmits over a channel, with no secret stored on the person's side. Its function is to add a second factor to an authentication that, with the password alone, depends on a piece of data that could have leaked.

What changes is what enters the calculation together with the shared secret. HOTP uses a counter that advances with each generated code, and the result does not expire by time, so a code that was issued but not used stays valid until it is consumed or the server resynchronizes. TOTP uses the clock and generates a new code per time window, usually 30 seconds, which closes its own validity. That is why TOTP is the most used in authentication apps: it shortens the useful life of an intercepted code without asking the user for anything.

It is better than having no second factor, and it is the weakest of the ones that exist. The code travels to a phone line, not to a device, and whoever controls the line receives the codes. That is exactly the result of SIM swapping, where the attacker gets the carrier to reassign the number to a SIM of their own. For high-value operations it is worth moving the factor to an authentication app, which calculates the code on the device and does not depend on the mobile network.

One identity, one SDK

VU ONE brings identity verification, authentication and fraud protection together on a single identity graph.

The verification you run at signup stays available to authentication and to your fraud rules, with no repeated processes and no duplicated data.

Verify, Authenticate and Protect, consolidated in one place.

Request a demo