Skip to content

Google Authenticator One-time Password Algorithm in Javascript

I’ve recently setup 2-factor authentication on my Google account.  The new 2nd factor or “thing you have” is a smartphone application which generates 6 digit one-time passwords.

I was a bit surprised when I stumbled on this article Two Factor SSH with Google Authenticator. Turns out the algorithm used to generate the OTPs is an open standard. When you set-up an account in the smartphone app you are storing a key that’s used to create a HMAC of the current time.

You can read the specifics of the algorithm in the TOTP RFC Draft.  I really like the idea that you can use the smartphone app to generate OTPs for your own application.  I’ve implemented the algorithm in javascript on jsfiddle.   Javascript is nice and readable, but please don’t implement your verification client side! 🙂


  • 2012-Sept-6: jsSHA moved location
  • 2012-Sept-12: Something suspect about the way I’m converting BASE32 to bytes. Changed it to grab full bytes from the binary string, and ignore anything left over.
  • 2014-April-22: Github not a CDN anymore.. 🙂 Moved references to bootstrap and jsSHA

{ 36 } Comments

  1. Mark Linton | January 28, 2012 at 6:41 am | Permalink

    Great JS example of the TOTP algo. It would be really awesome to have the actual OTP generation explained using the same example (how the offset it calculated, etc).


  2. russ | January 28, 2012 at 9:42 pm | Permalink

    Hi Mark, your timing is good. I’ve just been playing with this the TOTP algorithm on an Arduino. See here:!/russaus/status/163232099220996096

    I’ll do a blog post on the Arduino stuff soon, and I’ll include an intro to the algorithm with the post.


  3. Markus | March 1, 2012 at 1:41 am | Permalink

    See for an example on how to compute the TOTP in Javascript without requiring additional libraries. I don’t claim that the code is readable — but I do claim that it is compact.

  4. Gerard Braad | June 7, 2012 at 11:59 pm | Permalink

    Created a small Gnome Shell extension based on your publication:

  5. russ | June 16, 2012 at 9:38 pm | Permalink

    Hi Gerard, I’d love to see your Gnome shell extension in action. Can you post a screenshot somwhere?

  6. Annon | June 16, 2012 at 6:01 pm | Permalink

    Im loving the dead beef in the key 🙂

  7. Gerard Braad | June 17, 2012 at 2:21 am | Permalink

    Hi Tin, took some time to ‘productize’ the implementation. Made it into a small HTML5 app for use in any browser: and even a Chrome extension: or a phonegap build:

    The gnome extension is not been approved as of yet, since I still have to optimize it a little to only run on dialog popup and use the HMAC implementation as provided by glib.

    Have attributed you in the code and will do so in an about box. All stuff is published on github.

  8. Gerard Braad | June 17, 2012 at 7:47 am | Permalink

    oops, correction… Hi Russ…

  9. russ | June 17, 2012 at 7:49 am | Permalink

    heheh… not the first time I’ve been called ‘Tin’ 🙂

  10. Andrew Stanley | January 24, 2013 at 7:40 pm | Permalink

    Russ, did you ever get around to documenting what you did with your Arduino? I’m futzing with the same idea right now and would love to see your example/write up!

  11. russ | January 26, 2013 at 2:06 am | Permalink

    Hi Andrew,
    I didn’t get around to writing anything up. The source code is here:
    Will _try_ get around to documenting it someday!

  12. FJH | January 22, 2014 at 4:31 pm | Permalink

    This wonderful example has stopped working in Chrome as Chrome now enforces strict mime type checking. Still works in Firefox though.

    Refused to execute script from ‘’ because its MIME type (‘text/plain’) is not executable, and strict MIME type checking is enabled.

  13. russ | April 23, 2014 at 3:14 am | Permalink

    Hi – I think I’ve fixed the the problems that were breaking things in Chrome.

  14. FJH | April 23, 2014 at 5:45 pm | Permalink

    I agree, you have fixed the issue that stopped it working in the latest version of chrome. Thanks.

  15. Sneezry | July 10, 2014 at 12:32 pm | Permalink

    I created a Chrome extension based on your work (, nice job, thx!

  16. russ | October 5, 2014 at 5:21 am | Permalink

    Your extension looks REALLY cool!

  17. dh | October 4, 2014 at 2:24 pm | Permalink

    Hi, Russ. This is a very useful reference. That said, could you confirm the code still outputs correct OTPs for Google? I have used my own secret key retrieved from Google with the code above only to see it fail. I have used the same secret key with the third-party OTP generating apps on my mobile and they have worked. Any insight sharing will be deeply appreciated.

  18. russ | October 5, 2014 at 5:17 am | Permalink

    Hi, I regularly use the jsfiddle link when I can’t find my cellphone for OTP (and I just tested it with my AWS and google secrets). If you captured the secret from the google QR it will look something like this:

    Are you grabbing the “secret” portion only? i.e. in this example you only want JBSWY3DPEHPK3PXP.

    Let me know if are still having problems with this.


  19. meh | October 15, 2014 at 4:18 pm | Permalink

    Hi there,

    I’m trying to figure this out too. Like dh said, I’m trying to get my Google Authenticator to show the same passwords on the above implementation and in Google Authenticator and I’m failing 🙁

    One thing I noticed was that the secret parameter they’re passing in the QR Code is not base 32 encoded, they’re actually displaying the 32 character secret key that you’d type in to Google Authenticator if you couldn’t scan the QR code.

    I tried taking that and base 32 encoding it and putting the result in above, but it didn’t show the same OTP either. Is there another step I need to do to take Google’s 32 character string and get it to work in the Secret field above? I’m kind of new to this, and haven’t read the RFC completely yet. Sorry if it’s a n00bish question 🙁

  20. meh | October 15, 2014 at 4:23 pm | Permalink

    oh my word.

    Never mind 🙂

    while I was writing this I realized that the 32 character code IS the base 32 encoded string and didn’t need to be encoded again. I’m a dummy 🙂

    I see my initial comment is still waiting moderation. You can feel free to ignore that and this one too LOL.

    Thanks for the killer implementation and for helping me understand how this works! 🙂

  21. russ | October 15, 2014 at 4:25 pm | Permalink

    Glad you got it working! 🙂

  22. dh | October 17, 2014 at 7:43 pm | Permalink

    Yeah, I just realized the problem was that the base 32 encoded code Google provides had whitespace which the base32tohex function did not handle properly.

    I just added

    base32 = base32.replace(/\s/g,”);

    to strip all whitespace in the base32 input and now it works like a charm.

    Thanks Russ and Meh.

  23. Andy Ibanez | December 24, 2014 at 6:35 pm | Permalink

    When refreshing the page, how do you keep the code and still know how much time is left before expiration? Are you using the offset for that?

  24. russ | December 24, 2014 at 6:42 pm | Permalink

    Hi Andy, I recalculate the code every time the page is loaded. The code changes every time “unix_time mod 30” changes, i.e. every 30 seconds.

  25. Andy Ibanez | December 24, 2014 at 7:26 pm | Permalink

    russ, thanks.
    I’m trying to implement a TOTP generator for iOS grabbing libraries from different sources but nobody seems to do the token life thing right. I will try to use your method to generate a token and see its real life time.

    Thanks again.

  26. Sneezry | February 2, 2015 at 5:45 am | Permalink

    Hi, Russ

    I, the guy made a Chrome extension based on your work, want to ask you a question: I want to open source my work under Apache License, but I failed to find out the license you publish your work under, if you publish it under GPL License, Apache License will conflict that. So please let me know whether I may open source my work under Apache License. Thx.


  27. tsonev | June 29, 2015 at 11:48 am | Permalink

    A note to all about timebased tokens and this implementation in particular:
    It is crucial that the machine on which the token is generated and the machine that is verifying the token have synced time down to the second, otherwise the tokens will not match! As was the case on my Mac which is behind company FW and automatic time sync protocol was forbidden.

  28. russ | July 30, 2015 at 11:45 pm | Permalink

    The is true, the spec for TOTP does say:

    A validation system SHOULD typically set a policy for an acceptable OTP transmission delay window for validation. The validation system should compare OTPs not only with the receiving timestamp but also the past timesteps that are within the transmission delay.

  29. Hugh Perkins | March 4, 2017 at 11:35 am | Permalink

    Hi. Great work! I’d like to make a fork of your code on github, so I can use it as a web-based authenticator, without worrying your site will disappear, etc.

    Can you confirm that your code can be used under an opensource type license, eg MIT, or Apache License 2.0? Please can you confirm explicitly which license you are confortable with licensing your code under?


  30. russ | March 6, 2017 at 9:18 pm | Permalink

    Hi Hugh,
    I’m happy to go with an MIT license:

  31. Hugh Perkins | March 4, 2017 at 12:32 pm | Permalink

    (Note: I have forked the code to here: Please let me know if this is/isnt ok)

  32. russ | March 6, 2017 at 9:19 pm | Permalink

    All good! Let me know if there’s anything I can contribute on the project.

  33. Simon Adams | February 24, 2019 at 5:28 pm | Permalink

    Hi Russ,

    I am a complete beginner but have managed to utilise your code to be able to be read by wix with some significant help and support from wix members, I am keen to know how to add the verification piece to my wix website in JS. Please do let me know if you’re able to help. Best wishes Si

  34. russ | February 24, 2019 at 10:57 pm | Permalink

    I’m not familiar with wix websites. I say in the article:

    please don’t implement your verification client side

    If a wix website is entirely client side then I wouldn’t recommend this approach. You definitely need a server hosted component to verify this type of authentication.

  35. Mateus M. Côrtes | February 19, 2019 at 5:41 pm | Permalink

    I used your code on a NodeJS module, it’s ok if I publish it? If I can, under what license?

  36. Jay | February 23, 2019 at 7:54 am | Permalink

    I’ve converted this snippet into a handy Javascript class (for better code reusability and integration). It can be found here:

    Great job, russ! I’ve credited you in the comments.

{ 5 } Trackbacks

  1. […] oder.Eine interessante Seite um etwas mit dem Secret, dem QR-Code und dem Code herumzuspielen ist diese Javascript-Umsetzung.Für WordPress gibt es ein Plugin für die Google Authenticator Unterstützung, ich nehme an dass […]

  2. […] Liens utiles : RFC 6238 – TOTP: Time-Based One-Time Password Algorithm RFC 4226 – HOTP/IETF Exemple de calcul d’OTP TOTP generator in javascript […]

  3. […] Liens utiles : RFC 6238 – TOTP: Time-Based One-Time Password Algorithm RFC 4226 – HOTP/IETF Exemple de calcul d’OTP TOTP generator in javascript […]

  4. […] Liens utiles : RFC 6238 – TOTP: Time-Based One-Time Password Algorithm RFC 4226 – HOTP/IETF Exemple de calcul d’OTP TOTP generator in javascript […]

  5. […] 其实我最近玩google authenticator 体验不错,稍作努力就可以搞定两步式动态密码验证,这里有网页版的实现: —————————————————————————————————————————————————— ↓ 解决方案 ↓ […]

Post a Comment

Your email is never published nor shared. Required fields are marked *