I write things here.

The archive.


I was at Devops Days London a few weeks back, and there I heard Ben Hughes from Etsy talk about security. Amongst the many interesting things he said, he raved a little about his YubiKey. I was dimly aware that such things existed, and assumed that they were hardware versions of Google Authenticator and other things which provide TOTP-based 2-factor authentication tokens for various things.

Hearing someone rave about how useful they were, I decided to take a punt and bought one. Initially, I was going to buy a ‘standard’ one, but after an off-hand comment about “how great would it be if they supported NFC” and someone telling me that “The NEO ones do!”, I bought a NEO.

It’s not cheap. $50 is not a ‘disposable’ amount of money. But I guess they have no competition at the moment. Hopefully prices will come down.

It showed up a few days later. I was fully expecting to be able to instantly start using it as a TOTP token and store all the 2FA secrets for all the online services I use 2FA for on it.

Turns out, it’s not quite that simple.

The YubiKey as a device cannot do TOTP by itself. The TOTP protocol is time-based (hence the name - Time-synchronized One Time Password) and to work properly needs a clock. The YubiKey doesn’t have a clock. It does support HOTP as well as being implementing a keyboard via its USB interface: plug this thing into a computer and it sees it as a keyboard. Press the button on the YubiKey, and a random string (prefixed with the device serial) is ‘typed’ into wherever the cursor is.

I couldn’t initially see how this would be useful to me. Google, Amazon, Dropbox - all their 2FA mechanisms use a TOTP workflow. After a bit of digging around, it turns out that there is a way of making the YubiKey do TOTP, it just needs a clock source, such as…… a phone!

There’s an Android app called YubiOATH (open sourced at Github) which is designed to make a YubiKey NEO work in exactly the way I need. When you enable 2FA on an account, you typically get a QR code to scan which contains the 2FA ‘secret’. With something like Google Authenticator or Authy, that secret is stored on the phone itself. Then, when you next log in, it generates the relevent code. With YubiOATH, you snap the QR code with the app and then NFC-connect (there must be a better verb for that?) the YubiKey - the secret gets transferred to the YubiKey. To generate a code, just run the app, NFC-connectify the YubiKey and all the accounts for which it has a secret will have a code generated which expires in 30s. The phone never sees the secret, it just provides the clock and communicates with the YubiKey to get the code. The upside is that this works on any NFC-enabled device with the app installed. The downside is that if someone pinches your key, they can in theory get the codes. There’s an option within the app to set a password on the key, which ideally would further encrypt the secrets on the YubiKey. I don’t know how easy that is to get around though.

So you buy a YubiKey, and install the app. Surely it works out of the box? No. There’s some hacking you have to do first. You need to faff around with some software somewhere and install an applet to the YubiKey which lets it support this - I couldn’t install this from Linux, but it seemed to work from Windows. I gather the NEO is going to start shipping with this built-in at some point which would save some head-scratching. It’s certainly not for the non-technically minded. Once done, you don’t have to think about it again though.

So, the whole point then is to store the 2FA secret not on your phone, an untrusted device with a large attack surface, but on a dedicated, (supposedly) secure, small piece of hardware. It seems to do this rather well. I had previously switched from the Google Authenticator to Authy, as the Google app provides no functionality for migrating your secrets to a new device. If you lose or change your phone, you have to reset the 2FA code on every account you use it on. Authy attempts to solve this problem by uploading an encrypted version of the secret to their servers, so when you activate a new device, you can download the secret and decrypt it. The issue is still that the secret is stored on the phone, which you may not choose to trust.

With the YubiKey, the 2FA secret still goes via your phone, but only at the point where you scan the QR code and load it onto the key. A bad thing could still sniff that at that point, but there’s a big difference between placing trust in a device at a single point in time, versus trusting it for the foreseeable future. If you’re hyper-paranoid, you could ‘airgap’ this and have a dedicated android device with just the YubiOATH app installed, and no network connectivity, and use this to do the QR-code scanning and loading to the YubiKey. But I’m not that paranoid.

In summary, I like it. It’s supposedly waterproof and almost indestructable, and does the job well, once you’ve got it set up. You don’t have to use it in this way, there’s lots of other ways which didn’t seem particularly useful to me. If I lost it, I’d get another one.