Wednesday, November 27, 2013

Why Google Needs to Update Their Two-Factor Authenticator/TOTP System


So those of us that are security and hacker conscientious use two-factor authentication for our online and work accounts whenever possible. 

Basically two-factor authentication is the concept that your User Name or ID is something you are (which you have to prove), your Password is something that you know (the first factor of proving you are who you say you are), and something that you Have (the second factor of proof).  So for example, your cell phone that can receive a text-message or an e-mail generated by the system with a unique one-time code when you try to log in with a user name and password is a two-factor system. 

Another example is a system where the server and the user know a shared secret (other than the password).  This secret was established during user enrollment, and is used, along with a known, shared counter, or some kind of time-code, to produce a PIN that is only usable once, and thus changes with each log-in attempt. 

Google uses this second system.  Twitter and Yahoo use the first type of system.  Microsoft offers a two-factor system but I haven't played with it yet.


Google uses the open standard TOTP (RFC 6238), which is nice because everyone knows exactly what it is, how it works, and how secure it is because everything is transparent like you would want in a Crypto based system.  They developed their own app which is available for all major mobile devices (but no desktop app; author’s plug: I wrote one myself in .NET, it’s available HERE at CodePlex).  This produces 6-digit codes every 30 seconds, according to the default assumptions in the standard.

When you sign up for the two-factor system, they provide a barcode that is basically a URI string, defining the properties of the account, which you can scan with your phone (or a simple Base32 string you can type into a device that has the app but no camera).  They also provide 10, 8-digit “emergency” codes that are one-time use in case you need to get into your account but have lost your device.

What they did, though, when they set up their system is in the app and the registration process, they ONLY use the defaults (each code has a 30 second “period”, every code is 6 digits long, and the SHA1 hash is the core algorithm, with an 80-bit secret key; this key is the only piece of actual information they provide as it is the only thing that changes between users).  The fact that they only implement these defaults means that the Google Authenticator app is basically ONLY usable for Google sign-in, unless you happen to have a system that uses the EXACT same defaults.  I’ve tried using different URI strings on the app, and the app ignores them all, and it even truncates any secret keys you provide that are longer than 80 bits.  Frustrating.

(Note the program also supports HOTP, defined in RFC 4226, but time-based codes are more common in the "wild", and I'm not discussing the HOTP side of the app in this article)


First, they can update their app to fully implement the standard URI format and allow for different “periods”, digit-lengths, hash algorithms (such as anything in the SHA family including the new SHA-3 standard when it finally gets codified by NIST, or other widely popular algorithms, like WHIRLPOOL, RipeMD160, etc.), and for any length key between 80- and 512-bit.  This would allow a larger number of users and system administrators to use the Google app as the standard for user-device acceptance.  The Bring Your Own Device (BYOD) movement is already strong in the marketplace, so why not take advantage of it.  RSA doesn’t have to be the only leader in this field.

Second, they could update their system to use stronger secret keys (>80 bits), and a better algorithm (like SHA2-384) as their own, new defaults.  Since they already have to have a DB or a table somewhere with these 80-bit keys for their users, they could add the fields necessary to store the additional system information (or simply widen the fields for the longer keys) and a flag for which algorithm the user is enrolled with, such as the v1 algorithm (SHA1) or v2 algorithm (SHA2-something).  This wouldn’t increase their data usage by any unmanageable amount and still allow their legacy two-factor users to log-in until they updated to the new order.

In the meantime, Google has released their Authenticator code to the world on their code repository site (, so any other programmers could take up that torch and do what they are doing only better, and then Google could just publish their updated standard to allow the app writers to adjust.

Either way, as much as their two-factor system is a great start for security, in the wake of GPU-based password hash crackers and the bevy of NSA leaks, I think they need to be doing a lot more going forward.


First off, the old DES encryption standard uses a 56-bit key, which with modern hardware, can be deciphered in about 4 minutes (using specialized, but not terribly expensive equipment).  Eighty bits is not much longer, and given an attacker might be able to skim 2 or 3 codes from a user by “shoulder-surfing” his phone at an airport or coffee-shop, he can then use these new GPU-based hash crackers (which are freely available on the Internet, just search “hashcat” as one example), he could brute-force attempt to find out what the 80-bit key is. 

The attacker can verify his efforts, even if he doesn’t know the target’s username/password, by using the time-codes that would have been used by the target’s phone/device when the attacker surfed the TOTP codes to reproduce them (remember, all cellphone companies broadcast the time to within about 30 seconds of most Internet time servers, so that information is not difficult to get at all, and we all know the algorithm Google uses to generate those time-codes, and that the TOTP-codes are produced every 30 seconds by default).

The TOTP algorithm does have a method to try to thwart such a reverse-engineering attempt (the final 32-bits used internally to generate the final 6-digit TOTP-code are taken from different parts of the internal hash based on a value in that hash, so the location changes every time), but at 80 bits, Google’s current secret just isn’t long enough to stave off modern (and especially distributed) brute-force efforts that ignore that extra step.


Google, increase your secret-key lengths, and make your app more adoptable by, I dunno, adopting the full standard in the first place!