What is two-factor authentication and why should you care?

It is no surprise that security is a hot topic when building a modern web application. As the CEO of Ashley Madison could probably tell you, having your account stolen is not only annoying, it can be downright embarrassing. Having just a password is no longer the secure option it once was. Users are vulnerable to social engineering or simple carelessness if they leave passwords on sticky notes attached to their monitors. A password can also be revealed through the use of brute-force techniques by hackers. For these reasons, it’s no longer a question of should Two-Factor Authentication be implemented in your web application, but rather when.

For those unfamiliar with the term, Two-Factor Authentication, or 2FA for short, is an extra layer of security added to the login process. Users first enter their usernames and passwords, and if they are valid the application will prompt for a Two-Factor Authentication code, which can be found on a device carried on the person — usually the user’s smartphone. Physical 2FA devices exist, such as the RSA SecureID keyfob, but they are less common in the workplace. 2FA authentication codes are 6 digits and can be safely generated by authentication apps like Google Authenticator or Authy. The code is dynamic, with a new one generated every 30 seconds, meaning you must have physical access to the device in order to retrieve the code.

Where to start?

In order to use 2FA, users must first connect an authenticator app, either by entering a code or scanning a QR code with the authentication app. Thankfully, Google has a link developers can easily use in their application code to create a QR code for a secret key. This secret key is a unique, 16-character, base32-encoded value saved on your user model in your application database. It will be used later to generate a dynamic 6-digit code used to authenticate that user.

This is how a typical QR code link would be constructed:

https://chart.googleapis.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/{{ label }}?secret={{ secret_key }}"/>

There are two parameters in the URL that should be noted: the label and the secret key. The label will be whatever is displayed as a title for the key on the user’s 2FA code. It can be a combination of your product name and the user’s email address, or the user’s username (ie, Sendwithus:marie@sendwithus.com). Once a secret key has been generated for your user and a QR code has been displayed in the app to be scanned, you’ll need to implement an algorithm to generate 2FA codes based on a formula. This is the most complex part of the implementation.

At Sendwithus, we use the TOTP (Time-based One-time Password) algorithm when implementing 2FA. It is a fairly straightforward formula using the stored secret key and the current timestamp to generate a 6-digit code. The user’s authentication app will use the same TOTP algorithm, but on the authentication device. This ensures the authentication code generated by your web application and the code displayed on Authy or Google Authenticator will match.

The steps are as such:

  1. First, generate a secret key (a unique 16-character base32-encoded code) and save it on your user object (or somewhere secure in your database). This should be the same secret key you use to generate the QR code for the user to scan.
  2. Generate a timestamp to use in the algorithm. As an aside, you probably want to use the current timestamp. Most products will also repeat the algorithm with one or two older timestamps, to allow for some delay between when the user reads their code, and when they actually enter it into your application.
  3. Decide which hash method to use. By default, TOTP uses SHA1 so that’s what we decided to use.
  4. Generate a 6-digit authentication code using the TOTP algorithm below.
#turns a unix timestamp into a byte string

bytetime = self._time_to_byte_string(timestamp)

hmac_hash = hmac.new(

base64.b32decode(secret_key, casefold=True),




# Generate code from hmac

offset = ord(hmac_hash[19]) & 0xf

code = ((ord(hmac_hash[offset]) & 0x7f) << 24 |

(ord(hmac_hash[offset + 1]) & 0xff) << 16 |

(ord(hmac_hash[offset + 2]) & 0xff) << 8 |

(ord(hmac_hash[offset + 3]) & 0xff))

# '6' is number of integers in the OTP

return code % 10 ** 6

(code snippet written by Joel Franusic @ Twilio)

Implementing SMS Authentication

Once that’s been done, there is also the option of implementing SMS authentication, thanks to the Twilio API. This means that a user can, after enabling 2FA, enter their phone number, verify it by receiving a code through a text, and then use SMS going forward to receive a 2FA code instead of going through an authenticator app. Some products allow two-factor authentication only by SMS, eliminating the need for an authentication app. However, we found this use-case rare and less secure. At Sendwithus, we made SMS an alternative option. If this is the route you plan to take, you will need to create a Twilio account and buy a phone number (around 1$/month). I mention Twilio as it’s the one I’m most familiar with but any SMS API will do the trick.

Implementation of SMS authentication:

  1. When a user enters their phone number, generate a code to send them for verification (doesn’t have to be a 6-digit 2FA code).
  2. Send the code in an SMS message (see code below).
  3. When the user enters the code, verify it’s correct.
  4. Only then, save the phone number on the user object.

Verifying phone numbers after verification of the first code eliminates the case where a user enters an invalid phone number and realizes it only later, when they try to log back in but the SMS API returns an error message.

Here is a code snippet to send SMS through Twilio API (using Python and the requests library):

# twilio_accound_sid and twilio_auth_token are your Twilio API Credentials
path = 'https://%s:%s@api.twilio.com/2010-04-01/Accounts/%s/Messages.json' % (twilio_account_sid, twilio_auth_token, twilio_account_sid)

to = '%s' % customer_phone_number

# twilio_phone_number bought through Twilio
from = ‘+%s’ % twilio_phone_number

# Body message containing the verification code
body = ‘Your verification code is %s’ % code

data = {
'To': to,
'From': from,
'Body': body

response = requests.post(path, data=data)

if response.status_code != 200 and response.status_code != 201:
raise GenericError("Error sending sms")

The Final Product

Finally, your application login process needs to be modified to allow 2FA authentication. Every web application is different and therefore your implementation may differ from ours. Regardless of your workflow, there are certain questions you should be sure to consider. For example, “How long should a user be allowed to linger on this second step?”. Meaning, is a user allowed to enter their username/password and leave their desk with this open. Should this step timeout after a couple of minutes to avoid someone coming in and trying codes? To handle this, we chose to require that users provide a valid 2FA code within 60 seconds of entering their password.

Screen Shot 2016-03-03 at 3.05.19 PM

What about recovery codes?

Recovery codes are a list of one-time codes generated when you turn on 2FA. A user then saves them somewhere safe on their computer or prints them off to have a hard copy. They allow access to your app in case the user loses (or breaks) their phone. It’s important that recovery codes can only be used once. Otherwise, a user might use it as a second password which would defeat the purpose of two-factor authentication (especially with autofill turned on). The list of recovery codes should be stored securely, similar to the user’s secret key.

Technical Pitfalls

Unfortunately, 2FA is not impossible to crack. An even better system would be three-factor authentication with biometrics verification (retina scans, voice recognition, fingerprint scans…). However, for most applications, 2FA is a smart and secure option.

I also didn’t cover any of the database implementation details. It’s up to you and your team to decide how the data should be stored and encrypted. You should also go over how this data will be communicated between your database, the backend, and frontend, as you will have to ultimately pass the secret key to show the QR code to the user. Again, of course, those solutions are dependent on your application.

Closing Notes

I hope this guide helps you in your implementation of 2FA. If you still don’t feel comfortable, there are many TOTP libraries that you can use. You may also use Authy API to handle 2FA for you. However, coming from someone who just implemented 2FA for the Sendwithus platform, it’s much simpler than it seems at first. Go and give it a try!