The core algorithm/TOTP implementation used by GAuth
Ref: http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/
The core algorithm/TOTP implementation used by GAuth
Ref: http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/
// http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/ | |
function dec2hex(s) { | |
return (s < 15.5 ? '0' : '') + Math.round(s).toString(16); | |
} | |
function hex2dec(s) { | |
return parseInt(s, 16); | |
} | |
function base32tohex(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; | |
} | |
function leftpad(str, len, pad) { | |
if (len + 1 >= str.length) { | |
str = Array(len + 1 - str.length).join(pad) + str; | |
} | |
return str; | |
} | |
function updateOtp(secret) { | |
var key = base32tohex(secret); | |
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(key, 'HEX', 'SHA-1', "HEX"); | |
//qrImg = https://chart.googleapis.com/chart?chs=200x200&cht=qr&chl=200x200&chld=M|0&cht=qr&chl=otpauth://totp/' + account + '3Fsecret%3D' + secret; | |
//var keyLength = (key.length * 4); | |
var offset = hex2dec(hmac.substring(hmac.length - 1)); | |
//var part1 = hmac.substr(0, offset * 2); | |
//var part2 = hmac.substr(offset * 2, 8); | |
//var part3 = hmac.substr(offset * 2 + 8, hmac.length - offset); | |
var otp = (hex2dec(hmac.substr(offset * 2, 8)) & hex2dec('7fffffff')) + ''; | |
return (otp).substr(otp.length - 6, 6); | |
} | |
function timer() { | |
var epoch = Math.round(new Date().getTime() / 1000.0); | |
var countDown = 30 - (epoch % 30); | |
if (epoch % 30 == 0) { | |
updateOtp("JBSWY3DPEHPK3PXP"); | |
} | |
return countDown; | |
} |
how about to make it work in nodejs without jsSHA but using the native module crypto ?
Patches are welcome. This hasn't seen modifications since 2012, and is still used this way in gauth (From the browser). Compatibility is key...
Patches are welcome. This hasn't seen modifications since 2012, and is still used this way in gauth (From the browser). Compatibility is key...
I think you mean https://chrome.google.com/webstore/detail/gauth-authenticator/ilgcnhelpchnceeipipijaljkblbcobl
But that's from you not from google :D
Link is in the gist.
I think you mean https://chrome.google.com/webstore/detail/gauth-authenticator/ilgcnhelpchnceeipipijaljkblbcobl
Yes, that is actually my extension. I suggest you to read more carefully, as the gist says this is the core of the GAuth tool.
With recent jsSHA that's how I got it to work:
I know this is some serious necrothreading, but this is still the best TOTP code I found for JavaScript. :)