Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Generate Time-Based One-Time Passwords With JavaScript

TwitterFacebookRedditLinkedInHacker News

I recently released an iOS and Android application called OTP Safe to iTunes and Google Play. OTP Safe makes use of the time-based one-time password (TOTP) algorithm commonly used with two-factor authentication (2FA). How exactly, does this algorithm work, and how can we make it work with JavaScript?

Using the following resources as our framework, we can make use of the TOTP algorithm quickly and easily:

For TOTP to work, we are going to need to make use of an HMAC function. JavaScript doesn’t natively have one, but lucky for us there is a great open source library called jsSHA that we can use.

A little background on two-factor authentication and time-based one-time passwords in general. Two-factor authentication is an extra layer of security that many web services offer. You enter your normal username and password followed by a six digit code that changes every thirty seconds. This six digit code is determined based on a secret key that both you and the web service share. The code changes based on the machines system time so it is important the web service and device have accurate times configured.

A complete and working version of my code can be seen below:

TOTP = function() {

    var dec2hex = function(s) {
        return (s < 15.5 ? "0" : "") + Math.round(s).toString(16);
    };

    var hex2dec = function(s) {
        return parseInt(s, 16);
    };

    var leftpad = function(s, l, p) {
        if(l + 1 >= s.length) {
            s = Array(l + 1 - s.length).join(p) + s;
        }
        return s;
    };

    var base32tohex = function(base32) {
        var base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
        var bits = "";
        var hex = "";
        for(var i = 0; i < base32.length; i++) {
            var val = base32chars.indexOf(base32.charAt(i).toUpperCase());
            bits += leftpad(val.toString(2), 5, '0');
        }
        for(var i = 0; i + 4 <= bits.length; i+=4) {
            var chunk = bits.substr(i, 4);
            hex = hex + parseInt(chunk, 2).toString(16) ;
        }
        return hex;
    };

    this.getOTP = function(secret) {
        try {
            var epoch = Math.round(new Date().getTime() / 1000.0);
            var time = leftpad(dec2hex(Math.floor(epoch / 30)), 16, "0");
            var hmacObj = new jsSHA(time, "HEX");
            var hmac = hmacObj.getHMAC(base32tohex(secret), "HEX", "SHA-1", "HEX");
            var offset = hex2dec(hmac.substring(hmac.length - 1));
            var otp = (hex2dec(hmac.substr(offset * 2, 8)) & hex2dec("7fffffff")) + "";
            otp = (otp).substr(otp.length - 6, 6);
        } catch (error) {
            throw error;
        }
        return otp;
    };

}

The above TOTP code can be used like the following:

var totpObj = new TOTP();
var otp = totpObj.getOTP("SECRET_HERE");

Don’t forget that you will need to include these libraries in your HTML file like so:

<html>
    <head>
        <script src="sha.js"></script>
        <script src="totp.js"></script>
    </head>
    <body>

    </body>
</html>

Just like that, you now have a perfectly capable way to generate six digit passwords for two-factor services. You can even use this code, like I did, in your JavaScript based Phonegap or Ionic Framework application.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.