What is a one-time password?

Traditional passwords have a couple of major drawbacks. First of all, if they’re long enough to be secure, they’re often difficult to remember, and that means people re-use them all the time. Secondly, if someone gets hold of your password, they can now pretend to be you until you change that password.

One-time passwords (often abbreviated to OTPs) aim to address both these issues; since they’re only good for one use, there’s no possibility of re-using them across services, and if someone gets hold of your one-time password after you’ve already used it, it’s useless to them.

A one-time password is a short alphanumeric code that a service will ask you for when you try to log in to it. There’s a few ways that you as the user can get hold of the code – either through the use of specialized hardware, or via e-mail, SMS, WhatsApp, or dedicated OTP apps like Google Authenticator – and once you present it to the service, the server for that application will be able to verify the code and authenticate you.

Why use them?

One-time passwords serve a couple of purposes. Firstly, they act as an additional authentication factor; if you sign in to a service with a password or with SSO identity like Google, that’s one authentication factor. Adding in another check, such as the ability to receive text messages at a given phone number, means extra security for your account. If someone wanted to impersonate you, they’d need to have both of those things – your password or SSO identity, and access to your text messages.

The second thing that they often do is to add a time and usage limit on the availability of that second factor. One-time passwords are only good for one login session (as the name suggests) and, in the case of _time-based_ one-time passwords (TOTPs) they usually only work for a given time window after they’re generated. Depending on the needs of the service in question, that time window might be something like 10 minutes or 24 hours. This means that in the event where someone does manage to get access to your text messages as well as your first authentication factor, that window of vulnerability is time-limited. 

How are they generated?

There are a few different usage patterns for one-time passwords. Some use specialized hardware, like a card reader for your bank card or a Yubikey. In these scenarios, the OTPs are usually generated using a time-based mechanism. The hardware will contain a secret seed value shared with the server, and an accurate clock. The current time can be used alongside that shared secret to generate one-time passwords. However, this usage pattern requires users to own one of these pieces of hardware, which are expensive and easy to lose.

Another usage pattern is to use authenticator software like Duo, Google Authenticator or Microsoft Authenticator. These apps allow smartphones to be used in place of the dedicated hardware mentioned above, and do not require the smartphone to have an internet connection. However, it does require users to have smartphones, and use cloud backups to avoid losing access to any accounts in the case when they lose their smartphone.

Both the above patterns don’t require communication between the service’s server and the user who is attempting to authenticate. This is an important thing to consider when thinking about multiple security factors, because if an attacker can steal your password or SSO identity, they will probably be able to steal a one-time password that’s communicated over the web to you. 

However, it also means that the hardware token owned by the user needs to be able to independently generate codes that will be accepted by the authenticating server. The time-based mechanisms do this, and there are also other mechanisms such as HMAC, (which uses an increasing counter instead of a synchronised clock).

Both the above methods can be very secure when correctly implemented, but they require users to have access to specific hardware. Not all users have smartphones, and this is part of why one-time passwords over SMS have become so prevalent. Transmitting OTPs over SMS is less secure than using hardware to generate them locally, but it’s far more straightforward to implement, and more widely accessible to a range of users.

When sending OTPs over SMS, there’s no need for specialized algorithms to generate them. The server can generate them, send them to the user’s phone number which has been previously registered, and then validate the password when the user enters it into the front end of the service. All that’s required is that the passwords be random enough that anyone listening in cannot guess the next OTP by seeing any previous ones, and this isn’t a difficult thing to achieve computationally.

However, when using one-time passwords which are sent to the user (rather than generated locally by dedicated hardware or a smartphone), there’s always a risk that someone could intercept them. SMS messaging, while widely accessible and cheap to implement, isn’t encrypted, and the signalling system used by telecoms networks is vulnerable to certain kinds of attack. Email and WhatsApp are more secure methods for sending OTPs.

How can I implement them?

If you want to implement 2FA OTPs using an authenticator app, check out the library ecosystem for your particular framework or deployment pattern. For example, the django-otp package for Django and the otplib npm package streamline the experience for Django and JS-based frameworks respectively.

If you want to roll your own randomizer and send codes via email, SMS or WhatsApp, that’s possible too. All you’ll need to do is choose your preferred communication channel and store the appropriate contact details for each user, so that you know where to send codes once they’re generated.

If that sounds a bit overwhelming, we’ve got you covered: the Infobip APIs allow you to set up and manage one-time password 2FA in a straightforward and configurable manner. Check out our tutorials for SMS and WhatsApp!