TOTP: It's not Google Authenticator

I’ve been meaning to write about this since Twitter announced that only the eight-dollar-checkmark class would have access to SMS-based 2-factor authentication (2FA)1. Infosec circles got back into heated debates about the security implications of SMS-based authentication compared to the risk of losing access to the more-secure option of TOTP. This post isn’t really about that debate, but the major takeaways from either side are that:

User friction is a very real issue, and TOTP will always be more frictional than SMS; I can’t solve that in this post. Personally, I prefer to use TOTP when available due to the risk of a SIM-swapping attack2. This post, however, is more concerned with the matter of keeping your secret portable and within your control if you decide to use TOTP for 2FA.

If you’ve made it this far without knowing what TOTP is, well, that’s almost certainly by design. I would hazard that most people who are aware of it know it exclusively as Google Authenticator. Getting an increasingly-vital, open standard to be almost exclusively associated with one shitty app from one shitty company is certainly very good for that company, but very bad for everyone else. So the first order of business here is to clarify that whenever you see a site advertising 2FA via ‘Google Authenticator,’ what they actually mean is TOTP, or more accurately RFC 6238, an open standard3. Additionally, if you’re reading this and you currently implement TOTP on a site you manage or are planning to, I implore you to describe it accurately (including Google Authenticator as one of several options, if necessary) rather than feeding into the belief that the magical six-digit codes are a product of Alphabet.

So what, then, is TOTP? Even if you know it isn’t A Google Thing, the mechanism by which a QR code turns into a steady stream of six-digit codes is not entirely obvious. This is, typically, how we set up TOTP – we’re given a QR code which we photograph with our authenticator app, and suddenly we have TOTP codes. The QR code itself contains just a few pieces of URI-encoded data. This may include some specifics about the length of the code to be generated, the timing to be used, the hash method being used, and where the code is intended to be used. Crucially, it also contains an important secret – the cryptographic key that, along with a known time reference, is the foundation from which the codes are cryptographically generated. Essentially, a very strong password is kept secure, and from this an easily-digestible temporary code is generated based on time. Because it comes from a cryptographic hash function, exposing one (or more) of these codes does not have the same security implications as exposing the key itself.

Keeping the key itself secret is, in fact, extremely important. Vendor lock-in aside, I assume this partially contributes to the opacity of what happens in between scanning the QR code and having a functional 2FA setup. A large part of the debate over whether ‘Google Authenticator’ is a good 2FA solution is the fact that once your secret is in the Google Authenticator app, it is not coming out. If your app data gets corrupted, or if something misbehaves during a phone transition, you’re out of luck. Hopefully you’ve kept the recovery codes for your accounts safe somewhere. If to you, as to most people, TOTP means Google Authenticator, then this is a very real concern. One goof could simultaneously lock you out of all of your accounts that are important enough to you that you enabled their 2FA.

When I was de-Googling myself years ago, I went through the somewhat-laborious process of generating all new codes to put into Authy. In addition to (or in lieu of, I’m not entirely sure) local storage, Authy keeps your TOTP info in the cloud, allowing you to keep several devices in sync, including a desktop app. While this is a better solution than Google Authenticator, I’m not linking to it as I still think it’s a pretty bad one. The desktop app is an awful web-browser-masquerading-as-desktop-software creation. The system of PINs and passwords to access your account is convoluted. And, while in theory you can put the desktop app into a debug mode and extract your data, there’s no officially-supported path toward data portability. The unofficial method could go away at any time; in fact, while I will credit Indrek Ardel with the original method4, it seemingly no longer works and one must find more recent forks that do. On top of this, the aforementioned bad desktop app and confusing set of passwords meant that it was still just easier to start fresh with new codes when I recently switched away from Authy. Finally, Authy is another corporate product. It’s owned by Twilio, and they seem to want a piece of that lock-in pie as well, offering their own 2FA service that is a quasi-proprietary implementation of TOTP5, as outlined by Ardel.

For years, I’ve been using various KeePass implementations in conjunction with one another as a portable password management solution. I can keep a copy of the database in my OneDrive (or whatever cloud storage I happen to have access to; right now it’s OneDrive but frankly that’s because it’s cheap — not because it’s good) and have access to it from my phone and various computers. I can sync copies to flash drives if necessary, or drop a copy on an M-Disc with other important files to stash in a safe. I was, for a long time, using an unmaintained fork, KeePassX, because it simply vibes better with how I want computers to look and feel than its replacement, KeePassXC does. On mobile, I’ve been using Strongbox6. At some point, I noticed they added support for TOTP codes! The app will happily scan a QR code and add the relevant data to an entry.

This was interesting and novel, and I was already thinking about moving all of my codes into it, simply because storing them that way meant the data was easily recoverable. If I wanted to switch again in the future, I now had access to the secret and any other relevant parameters, and could generate a new QR code from them if need be. But then I happened to notice that KeePassXC, the desktop software I had been avoiding, also supports TOTP codes. And Strongbox’s implementation is fully compatible with KeePassXC’s! This changed things – suddenly this was a portable solution for accessing my TOTP codes and not merely the data behind them. I generated new codes for everything I use (and upgraded my security on a few things that had implemented TOTP without my noticing) and ditched Authy.

While you can add TOTP codes directly in the KeePassXC desktop app, you can’t do it directly from a QR code. Windows is fond of capturing screenshots to the clipboard7; I would love to see an option in KeePassXC that scans an image in the clipboard for a QR code (and then clears the clipboard). Getting codes out is extremely straightforward. Since the data is just in normal entries in my database, a code I scan in via Strongbox will show up in KeePassXC once OneDrive catches up. It is worth noting that this rather shatters the ‘something you know / something you have’ model of 2FA, but the flexibility is there to manage codes and passwords however the user is comfortable. The most important aspect for me was liberating my TOTP data from a series of lockboxes for which I lacked the key.

Ultimately, I don’t think average users care much about data portability until they’re forced to. By the time their hands are forced, the path of least resistance tends to just be to stick with the vendor that’s locked them in8. With TOTP, the ramifications of this can be extremely annoying. More importantly, however, I think Google has done a very good job at preventing users from even knowing that TOTP portability is possible. Whether I convince anyone to store their codes in KeePass databases or not is immaterial; I really just want people to know they have options, and why they might want to use them. I want people to give just a small amount of thought to the implications of having a login credential that you not only have zero knowledge of, but also have zero access to. Frankly, I want people to stop doing free advertising for Google. And finally, I genuinely want a return to an internet where, occasionally, we make our users learn one little technical term instead of letting multi-billion dollar corporations coöpt everything good.

  1. If you’re coming to this post without a basic understanding of 2FA, I’d suggest reading something like Proton’s introduction to the practice, as it’s a bit beyond the scope of what I’m hoping to cover here. The gist, however, is that a password alone is a single point of failure, and 2FA adds an additional security challenge in the case of a password breach, etc. ↩︎
  2. It is important to note that TOTP is not a panacea, there are other attack vectors to worry about. SIM-swapping, however, particularly freaks me out due to the potential for a social engineering attack. ↩︎
  3. Google Authenticator also supports HOTP, or RFC 4226, an increment-based OTP system. In practice, I’ve never seen this method used on its own, though it is itself the backbone of TOTP. ↩︎
  4. For the sake of crediting, Ardel’s gist can be found here. It’s unlikely to work, and in 2020 Ardel left a note recommending users seek out actively-updated forks instead. ↩︎
  5. Quasi-proprietary is, perhaps, a stretch – it just uses different defaults than most. Seven digits and a ten-second time block instead of six and thirty. Importantly, though, it also completely obscures the fact that it’s just weird TOTP from the user. ↩︎
  6. Strongbox has a MacOS app as well; I have not used it. ↩︎
  7. Phrased this way because I’ve lost track of how many inbuilt screenshotting mechanisms this goofy operating system actually has these days. ↩︎
  8. See: everyone still active on Twitter. ↩︎