A Guide to Implementing Multifactor Authentication
Website Design and Implementation
Overview of Multifactor Authentication
Multifactor Authentication increases website security by asking the user to provide two out of three possible authentication credentials:
- Something the user knows. (Typically this is the password.)
- Something the user has. (This can be some sort of device, such as a fob or key or a cell phone. Most commonly a cell phone is the designated device and that is what this paper will address.)
- Something the user is. (This typically means some sort of biometric such as a finger print or retinal scan. Because these are not commonly employed except in very high security settings and because they are expensive to implement, this factor will not be discussed in the present document.)
Multifactor Authentication is commonly referred to as Two Factor Authentication (TFA or 2FA) although Facebook calls it “Login Approvals” while Google refers to it as “2-Step Verification.”
When TFA is enabled by a website the username and password are initially verified; this is followed by an additional request by the server for a six-digit access code. This code is generated using a shared secret known to both the server and the user. If the user enters the correct code, authentication succeeds and the user is granted access, otherwise the authentication fails and the user is denied access.
Access codes are valid for short time periods, generally 30 seconds. Thus the user needs a way to determine the current access code value for very small time windows. This is typically accomplished by either sending the user the current code via SMS or by using a mobile application. The mobile application approach is considered the best practice.
Developers faced with the task of either implementing a new website or upgrading an existing website with TFA are faced with some additional considerations. First, they must provide for the routes and processing of the TFA user request and response. They must also expand their current persistent data stores to accommodate additional user information needed by TFA. Determination of the current access code for validation purposes is non-trivial and a source for potential error. Finally, an enrollment process needs to be developed that will involve a number of routes and screens; this enrollment permits the user to activate TFA and exchange the secret key required to generate access codes with the server.
All of these tasks can be mitigated by using standard libraries or code examples that are readily available on the Internet.
Some implementations include a feature similar to Google’s “app passwords.” This is because some desktop and mobile applications cannot respond to requests for an access code; an example might be Microsoft Outlook or Mozilla Thunderbird attempting to access a Gmail account. Special passwords are provided for these kinds of applications to permit them to log on successfully. App passwords are a serious breach of security. No viable solution to this problem has yet been presented.
A serious security flaw involves the password recovery process typically implemented by websites that require a login. Since password recovery takes place completely apart from TFA, any additional security protections provided by TFA are completely bypassed providing hackers with an opportunity for successful penetration.
This document makes frequent reference to Google’s implementation of TFA. It is assumed that this reflects the intended implementation by the reader. If some other implementation is envisioned, modifications may be required although the general methodology will remain the same. The general basis for this methodology is RFC 6238 ad RFC 3548 that should be used as a guide for any implementations.
The website logon flow is illustrated by the following diagram. It begins when the user contacts the website login page and concludes when access is granted.
User sends GET request to webserver ➔
← Webserver responds with login page
User provides username and password and sends POST request to webserver ➔
← If the user has been set up to receive six-digit codes via SMS, Webserver sends six-digit code to user via SMS. Otherwise this step is skipped.
← Webserver sends page requesting six-digit code
If the user has been set up to receive six-digit codes via SMS, user retrieves code from SMS message. Otherwise, user determines correct six-digit code by using the Google Authenticator App (or another equivalent third-party app.)
User provides the six-digit code and sends POST to the webserver. ➔
← Webserver receives the six-digit code. If the code is validated, user is granted access and webserver returns appropriate web page. If the code fails validation, webserver returns the page requesting the six-digit codes decorated with an appropriate error message.
User proceeds with website access or, in the case of an error, retries the six-digit code ➔
The most common algorithm, used by Google and other major websites, is called Time-based One-time Password Algorithm (TOTP). TOTP is based on another algorithm called HOTP or HMAC-based One-time Password Algorithm. The only difference between the two is that HOTP uses a counter that is incremented and used in the generation of the key while TOTP replaces the counter by referencing the device timestamp. There is a secret key shared by the server and the client (user) that along with the current timestamp and agreed upon parameters is used to generate the six-digit code used for authentication.
The parameters are generally the following. If the implementation elects to use an application such as Google Authenticator to determine the correct codes, then both the server and the client (user) must implement the same values for authentication to succeed.
- Secret Key
- Epoch (Default is Unix epoch)
- Time Interval that is the length of time a particular code remains valid. When the time interval expires the code becomes invalid and a new code is generated. (Default value is 30 seconds.)
- Cryptographic Hash Method. This is used during code generation. (Default is SHA-1.)
- Token Length (Default is six.)
A special note for Google implementation is that Google does not support parameters that are not defaults. Further, Google expects the secret key to be entered in base-32 encoding.
Since the six-digit code is determined by the agreed-upon parameters and the secret key, anyone can generate a currently correct code by using these parameters and assuming they know the correct time. Thus it becomes important for users who elect to use Google Authenticator or any similar app to ensure their phone has the correct time. Normally, this is handled transparently by the phone operating system. The server will likewise have access to an NTP server and know the correct time.
Regardless of the method used to receive six-digit codes (SMS or Google Authenticator) there is the possibility that a code will expire prior to the user’s ability to enter and return it. There is also a possibility for some time variance. For these reasons, most servers are programmed to accept the current value, the previous two time-period values, and the next two time period values, for a span of five time periods. Greater spans are possible with a corresponding reduction in security.
The setup for a user enrolling in TFA is similar to the Logon Flow above. However, the process begins with the user requesting enrollment by enabling TFA at the website. If the user indicates that he wishes to use the Google Authenticator app, the website presents a QR code that can be read by the app to complete the exchange of the secret key and establish an entry in the Google Authenticator database on the user’s cell phone. If the user has elected to receive codes via SMS the Authenticator steps are bypassed. The website requests that the user enter a current six-digit code in order to test the setup. (An incorrect setup can lock a user out of the system, so it is important to test the setup prior to actual activation.) The correct code is either sent to the user via SMS (if SMS has been elected) or the user launches the Authenticator application to obtain the currently correct access code. If the user returns the correct code the enrollment process is completed and further logons will be performed using TFA. An error in the test validation will result in additional opportunities for the user to correctly enroll.
Enforcement of TFA is a function of website programming. If TFA is being implemented by a website where the source code is under the control of your developers, then suitable design will ensure that users must always employ TFA or be denied access.
Google users must enroll themselves in TFA. Google recommends a two to four week period to give all users time to enroll themselves in TFA. By using the administrator setting Turn on enforcement from date, Google will remind users they need to enroll each time they log in and they will receive periodic reminder emails. On the ending date specified, users who are not enrolled will be denied access until they enroll.
It is also possible to place users in groups so that some G Suite users are required to enroll while others may not be. Google presents a comprehensive guide to setting up 2-Step Verification at https://support.google.com/a/answer/175197?hl=en&ref_topic=2759193.
Desktop and mobile applications that access G Suite resources are not able to enter six-digit codes. A primary example of this might be Outlook attempting to access a Gmail account. To accommodate this circumstance, users can set up special App Passwords to be used in place of their regular passwords on the impacted desktop or mobile application.
In some cases Google may determine that the application is not secure enough and may block login attempts from the Mail app on iPhone or iPad with iOS 6 or below. Also some instances of Microsoft Outlook and Mozilla Thunderbird.
Google presents a more complete discussion of this topic at https://support.google.com/accounts/answer/185833.
Note: Application Specific Passwords (ASP) severely compromise the security of G Suite since they completely bypass TFA. ASP in fact do not provide application limited access (since Google has no idea which desktop or mobile app you may be using for access.) In fact, ASP provide access to nearly all G Suite functionality.
Salesforce also implements TFA. The details of the Salesforce implementation are different from Google. Salesforce also has its own Salesforce Authenticator. Details of the Salesforce approach can be found at https://trust.salesforce.com/en/security/2fa/. There are also three Trailheads (Salesforce tutorials) listed that provide training for Administrators in User Authentication, Security Basics and Identity Basics.
Two Factor Authentication on User Developed Websites
Any website can implement TFA. From the preceding discussion it can be seen that this is a nontrivial task. The website will have to implement authentication routines that require a username and password at bare minimum. These will have to be stored persistently (e.g. in a database) to be useful. Adding TFA entails the initialization functions of enrollment, the exchange of a secret key, preferably by QR code (if an app like Google Authenticator is planned) or provision for the automatic transmission of the access code by SMS if that is chosen. Also the persistent store will require expansion to accommodate these additional items. Finally, the second level of authentication must be implemented to request and process the six-digit code from the user.
Details of this kind of implementation are beyond the scope of this present discussion, however the following comments can be made:
- Developers should avoid “reinventing the wheel.” The code required to generate six-digit keys is complex and error-prone. If a package is available that is already proven and that supports the site stack in use, then that should be chosen.
- For websites developed using PHP, visit https://phppackages.org and search for TFA, 2TF or Two Factor Authentication. Over fifty entries are available.
- For websites developed using node.JS, visit https://github.com/speakeasyjs/speakeasy and examine the README.md file. The package is a very comprehensive library for implementing two factor authentication as well as generating both HOTP and TOTP passcodes.
- The vendor website https://www.twilio.com/docs/tutorials has examples of code required for C#, Java, Node.js, PHP, Python, Ruby (Rails), and Ruby (Sinatra). Another set of examples covers similar material for using SMS authentication rather than a local app.
Several general comments can be made about the efficacy of TFA.
- While TFA improves security it is not perfect. Google “Two Factor Authentication Hacks.” This query recently returned nearly two million results.
- Using SMS as a method to transmit authorization keys to users is definitely not a best practice. Using the Google Authenticator is far safer. Authenticator is available in both Android and iPhone versions.
- No technology, no matter how sophisticated, can withstand clever social engineering attacks. One of the more famous attacks seems to be http://tech.firstpost.com/news-analysis/hackers-using-social-engineering-to-bypass-two-factor-authentication-321121.html. This kind of attack, by the way, can be mitigated by simply not using SMS to transmit authorization keys.
- Password recovery is a gaping hole in TFA. This is because password recovery completely bypasses TFA, allowing hackers to gain control of the user’s account.
- An educated, vigilant user is always an asset when trying to improve security. Spending some time educating users about common threats and how to avoid them can pay handsome dividends.