Category Archives: PHP

Yubikey’d Google Authenticator

I’ve been using Google Authenticator for over a year now. I used it for 2FA with just my Google Account (initially), then Dropbox, Amazon Web Services, and finally, SSH access to my servers. I must admit, I was feeling somewhat pleased that I actually have some resistance against keyloggers and shoulder surfers. Then my boss, when I was showing him the app, simply said, “well, but your phone is quite hackable.”

And unfortunately, he’s right – smartphones are common enough that malware and trojans for mobile devices are no longer a remote possibility. I could try to secure my phone, but it’s hard to be sure that a complex device with a smartphone is fully secure. My guess is, it’ll only be a matter of time before malware exists that harvests the secrets stored by applications like Google Authenticator, assuming they don’t exist already!

So, in February, I purchased two Yubikeys: one Yubikey Standard, and one Yubikey NEO. Yubikeys are 2FA tokens. Usually, you plug them in, they appear as a HID, you press the button, and it “types” a one-time password. They have a few modes of operation – they support static passwords, HMAC-SHA1 challenge-response, HOTP, and their own Yubikey OTP protocol. Yubikey OTPs need to be validated by a server, but Yubico does provide authentication servers for free. That said, I went ahead and ran my own authentication and validation servers. It takes a bit of effort, but it isn’t too difficult to set up.

The problem was, how do I migrate my existing Google Authenticator tokens so that I no longer have to rely on my phone being “clean”? Google Authenticator uses TOTP (the timestamp based version of HOTP) but the Yubikeys have no internal RTC and battery, so it’s not possible for them to generate TOTPs directly. You can use HMAC-SHA1 challenge-response together with a phone (over NFC) or a PC (over USB) to get the same functionally, but – there are only two memory slots on each Yubikey, so you can’t store more than two TOTP tokens per key.

My solution was to implement TOTP in a PHP application, and have that application verify a Yubikey OTP before generating and displaying TOTP codes. You can find the app I wrote here:

Note that in this scheme, it’s still arguably less secure than using the Yubikey on its own, but you do get to use a practically unlimited amount of TOTP tokens. And I would argue that it’s much easier to secure a server then it is to secure a smartphone.