How to Create a 2FA Generator: A Step-by-Step Guide
When you sign-in into a website or app, you enter your username and password. In a perfect world, these credentials would be enough to prevent the wrong people from accessing an account. Unfortunately, passwords can be easily decrypted or discovered using brute force or dictionary attack. Security is top-of-mind with the Sunrise Integration software development team so we are always looking for more secure methods.
To solve this problem, you can implement a two-factor authentication (2FA) layer. A 2FA is a random second password that the user cannot define themselves but must (usually an app, such as Google Authenticator or Microsoft Authenticator) identify which password is the correct one for a specific period of time.
Applying this extra layer of security is a very common practice nowadays and many companies big and small are implementing this method to protect their data.
In this tutorial we will code a software-based authentication using HMAC-based One Time Password (HOTP) algorithm, which is used by Google Authenticator and Microsoft Authenticator apps.
Step 1 - Third Party Scripts
In this example we use the npm package “jsSHA” to generate a HMAC hash. You can install using npm/yarn but to keep it simple we will just include the script on the page using a “script” tag:
Step 2 - HTML Elements
Next, we have to generate a unique secret(key) for each user. We could persist this value in a database but in our example let’s just create an HTML input field from where we can get the most updated secret:
We want the authenticator app to read a QR Code from our HTML page, so we have to create an HTML “img” tag to display the QR code:
Let’s respectively create HTML elements to display the current HMAC, one-time password and seconds left to update the key.
Step 3 - Constants
Let’s create some constants for our script:
Step 4 - HEX Value
We will create a function named “convertBase32ToHex” that will receive a base32 string and convert it to HEX. This HEX value will be used to generate our hash in the next step. Let's also declare two variables, one to store binary bits and another for the HEX value.
This ‘for’ loop will return a base 2 value based on the current base32 string length.
Now, we will get chunks of four characters from the “currentBits” variable and convert it to hexadecimal (base16) and return the hex value:
Step 5 - Hexadecimal to Decimal
Create a function called ‘convertHexToDecimal’, we will be using this function in the next steps
Step 6 – One-time Password HMAC
On this step we have to get the hexadecimal value and generate an HMAC. Let’s create a function name ‘updateOneTimePassword’. Then, define a ‘key’ variable to get the value from the input id ‘secret’ and convert it to HEX.
We will define a Unix epoch/Unix time, a function to convert decimal to HEX and calculate the current time based on the seconds to refresh our key.
Now we have to generate a HMAC based on our previously generated key and time. Note that we are using the ‘jsSHA’ package.
Let’s define a text to be used in our QR Code (‘authString’ variable) and update a DOM element with the current QR Code. In this example we are using QuickChart to quickly generate the image but you can use any package that you want.
Define an offset and break it into chunks of eight bytes/characters that are used for the moving factor.
Now we have to remove any child elements inside ‘HMAC’ div and assign a new value (part1, part2, part3 combined) to a DOM element just to see what is the current value returned to us.
Finally, let’s generate our one-time password and set the value to the ‘oneTimePassword’ div.
Step 7 - Timer
Now we will create a timer function that we will be called each second in order to change the value of a DOM element (‘currentTime’)
Step 8 - On load
Create a new function called ‘onLoad’ to create our first HOTP values and update the timer on the page.
Step 9 - Load it
Inside the <body> tag add an onload attribute to load our script, there are different ways to load a script when a page finishes rendering but we will keep it simple.
That’s it, you are done! Get your Google Authenticator or Microsoft Authenticator app and scan the QR on your screen to see the script working.
After you’ve finished writing your script and HTML elements, you should have a page similar to the image below. This code helps you to get started with a 2FA implementation for your website or app. For the next steps, you should properly store the user key and generate one key per user. Follow these steps and your system should be much safer than it was. Happy coding! :)