Klaus on Tilde Town

Using TOTP Two-factor Authentication like a pro

KeepassXC logo

I'll be the first to assume that I'm constantly learning new things about my computing usage these days, be they basic or advanced. I learn of new simple things that make me go "ohh snap! Why didn't I think of it?" and of power user-level stuff that changes my workflows completely as well. This is how my computing knowledge and experience grows, and it's how I mature my knowledge of using a computer - free software on it or not.

Thus, despite thinking that I had 1337 sk1LLz concerning password and credential management, I was quite surprised to learn just a few months ago about how you can set up two-factor authentication on the software that I last expected: Keepass.

If you learned how to use a password manager before, chances are that you already use Keepass or heard of it. It was the one I first tried about six years or so ago, and it remains the one I still do, but until very recently, I only used it to store passwords.

Sounds like a familiar situation? Then allow me to show you how you can take it one notch above. this time with your (time-based) 2FA.

WTF is TOTP 2FA?

The vast majority of two-factor authentication methods to online services (often called "tokens" by banks and financial services) is based on the Time-based One-time password method. I'm sure you've seen them before: six-digit codes shown in plain sight that change every 30 or 60 seconds. Enter them in correctly after your password and boom - you're in!

The first time I saw this in action, it had an almost magical aura to it. The bank or authenticator app generated a code and the website magically guessed it correctly, as though it had read my mind. And I also thought it was specific to those apps. Surely, only my bank's app could generate that magical, unique code, right?

Wrong! The algorithm for this is described in detail in the RFC 6238 of the Internet Engineering Taskforce, and anyone can implement it. In a very simplified explanation, it goes like this: a "hashed" message (more accurately, HMAC) is produced from a secret value known to two parties, say, a server and a client. To prevent a message from being re-used in the future by an attacker, the two parties add the factor of time into their calculations so that they can produce different messages in the future and validate each others' messages.

The strength of this is that the actual messages (the six-digit codes) are ephemeral; they become useless after a minute or so. This means you can combine them in with something more secret like a password and have two independent layers of authentication to match. The really important part of the TOTP is the permanent secret seed, which is the actually required information to derive the correct codes between the client and the server.

And because the algorithm is public, lots of Free Software implementations exist for it. Which takes me to the next point.

Adding TOTP to KeePassXC

KeePassXC is the latest implementation of Keepass, and it includes full support for TOTP tokens. The way you do set them up, though, is not very clear, and I had not discovered until recently. Here's the step-by-step.

Before you begin: set your computer's time correctly!

As you may have figured out from the previous description of the algorithm, a TOTP's value depends on the (computer) time that is used as input to the function. In other words, you and the server authenticating you must have the same time accurately set in order to work correctly - or at least that's what the server on the other side will assume of your computer. Come in with the wrong time set and guess what - future authentications may fail at the most random occasions!

Since time should be very accurately set, do not rely on looking at the wall clock in your house and using the date command. Instead, use something like the NTP protocol to sync your machine accurately to the second. Keeping it in sync with ntpd later is highly recommended, too.

Step 1: create a password entry if you haven't yet

You must have a password entry already created in order to add the TOTP to it. If you have used it before to manage your passwords, chances are that you already have several of them laying around. If not, click the plus sign button to add a new entry:

Keepass howto

Add your username and password (bonus points for using the random password generator in the dice icon instead of coming up with one yourself) and click OK.

Keepass howto

Your entry is created. Note that nowhere during this process could you add a TOTP to your entry!

Step 2: set up TOTP

Now that you have an entry created, you can set up a unique TOTP for it. To do so, right-click your entry and select Set up TOTP...

Keepass howto

A subwindow opens asking about the "Secret Key." You can get this key by going to the platform you want and seting up two-factor authentication. At that point, lots of online services offer you a QR code, intended to be read by a smartphone "authenticator" application. Here's the thing though: you can receive that code in plain text, too. Usually you'll have to click below it for an option like "I'd like to use a code instead" or something like that. This will give you the contents of that QR as a string of base32-encoded characters (like WBVAZ0nHOK0Ugrc) that you can enter in that KeepassXC window.

Keepass howto

Step 3: use your new TOTP

Your TOTP is now set. To use it, either click the clock icon in your entry to reveal the six-digit code, or copy it to your clipboard with Ctrl+T so you can paste it in the 2FA field directly.

Keepass howto

Step 4: back everything up!

Wow, that was easy, right? While you can rejoice now not using your smartphone to log into 2FA-protected services anymore, remember one thing: your TOTP secret is saved to your KeepassXC file. If you lose this file, guess what? You lose your TOTP and cannot log in anymore!

Thus, this is what you should do immediately after creating a TOTP entry: back it up. Go do it. Now. It can be as simple as copying it to a USB drive, or emailing yourself the file (you did set up a good main password, right?). However you choose to do it, back it up and remember to do another one every time you add new credentials to it.

Security considerations

With all that said and done and the tremendous amount of convenience received from this maneuver, there are still a lot of controversy in the security circles concerning it. Specifically, the bit of two-factor authentication is questioned when doing this.

The main complaint is this: multi-factor authentication was supposed to be strengthened by the combination of a password ("something you know") with an authentication means stored separately from the former ("something you have"). By storing all these secrets in the same database, at a first glance you're defeating this very concept, reducing the 2-factor authentication to 1-factor. However, I'm not too convinced of this.

For starters, the aforementioned model makes an implicit assumption that you must "know" your password - that is, you store it in your memory. The very act of using a password manager, however, changes this dynamic. You use one main password that in turn unlocks the place where actual passwords are supplied to each one of the services you use. In a sense, if you do this for every service you use online, you don't actually know any of your passwords at all!

Viewed this way, I'd argue that the password manager itself is a sort of two-factor protection mechanism; it requires one secret to access those credentials and, if you use an offline password manager like Keepass, you also need access to that file where those secrets are stored. Unlike the online model (where the service is basically exposed to everyone on the internet), just accessing that file on your computer is already orders of magnitude more complicated. This makes it much like that "something you know plus something you have" model.

Additionally, if your threat model requires such an extreme level of compartmentalization that you cannot afford to have TOTPs stored in the same location as the rest of the credentials, nothing stops you from having two different keepass databases, one for passwords and the other for TOTPs. Need even more compartmentalization? Place the TOTPs database in an external USB drive, or require an extra key file stored externally. You get the point.

Conclusion - your Freedom thanks you

The bottom line is that doing TOTPs this way is much better for Software Freedom than using whatever "Authenticator" "app" some corporate platform requires, not to mention much more convenient as well. It also makes it much, much easier to back up those TOTPs (if all you got is a smartphone, lose it and basically you've lost your life) and to use it on other devices (why must you have a phone to be able work? What if you couldn't afford one?).

TOTPs aren't the least magical, no matter how much "app" marketing wants you to believe, and thankfully there are a myriad of ways of doing it with Free Software. Here I presented what I use the most, but you can always choose other free software programs or even apps like FreeOTP+ if you absolutely must use a phone.

But please, oh please, do not use a proprietary "Authenticator app..."


Do you use TOTP on your Password manager? Do you think doing so has security issues? What would you use instead? Let me know on Mastodon!


This post is number #47 of my #100DaysToOffload project.


Last updated on 11/19/23