At linux.conf.au, we all got given a YubiKey each. These are a proprietary one-time-password generator device which plugs into USB and emulates a USB HID keyboard. Full documentation on how the algorithm works is provided by Yubico and they have also provided a lot of software for interfacing to the keys under a quite liberal BSD license. The device itself, being a USB HID device, needs no drivers other than what the operating system provides. Plug it in, press the button, and you get:
And don’t bother trying to use that, I have deliberately mangled some of the characters so it isn’t valid. (I’ve also used it in a few places since, so it’s old anyway.) The first 12-16 characters form the public ID, and are always the same, but unique for each key. The remaining 32 characters form the OTP data, and is encrypted internally using a 128-bit AES key. The data is a variant of hexadecimal called modhex — the digits have been mapped to keycodes that should be the same on every model of keyboard. This means the key will still work whether the computer is configured for QWERTY, QWERTZ, AZERTY, etc. Not sure if it handles Dvorak though.
I’ve been doing a bit of tinkering with mine. They can be used out-of-the-box with Yubico’s authentication servers for things such as OpenID. The programming tool however, lets you define your own parameters, and use them completely stand-alone. Yubico have a facility for uploading the key’s new AES key when you do this. The bonus with doing this is that you can use the same key for both stand-alone services you might set up, and for web-based services (with the caveat that it does open to replay attacks).
By the second day of the conference, I had my Yeeloong authenticating me using YubiPAM, a stand-alone PAM module. I’ve since configured my other laptop the same way, although I notice I get a buffer overflow when the authentication succeeds — not sure why as the Yeeloong works fine. I’m looking into what’s needed for Gentoo. I haven’t figured out how to get two-factor authentication to work there with KDM. I’m thinking maybe pam_python, and a homebrew solution may give me the flexibility I’m after.
Today, I had another look at it. This time, I was looking at what services I use that could make use of it. The obvious candidates: this blog, and OpenID.
On the OpenID front, I initially toyed with a copy of Yubico’s OpenID server, which is a very crude thing intended as a demo. I thought maybe I could extend it, but couldn’t figure it out. Figuring there must be a better solution, I went hunting, and found Community-ID. I managed to get Community-ID installed on my server without too much sweat, I had single-factor authentication using either a password or the YubiKey working in minutes. My instance is here, and now my devspace homepage functions as an OpenID, as does my blog.
As for two-factor authentication, I went digging for how it processed the password. Community-ID has a very strict model-view-controller structure that made things very easy. I wasn’t sure how to go about adding a new field, but I figured, I didn’t have to. The database stores the prefix so that it can identify who the person is logging in, and from that, I know the OTP will be the length of that prefix, plus 32 characters. I was able to modify Community-ID to take the last strlen(prefix)+32 characters, check that using Yubico’s servers, then process the remainder and compare that against the stored password. Bingo, two-factor authentication with one password field. The patch is already upstream.
Now if I can make YubiPAM do this, I’ll be very happy.
For the blog, I ended up doing both. I found a WordPress plug-in that does OpenID authentication. At first I couldn’t figure out how to link my new OpenID identity to my existing account, so I then turned to the YubiKey and installed a plug-in that performs that task. No sooner had I got that going, then I spotted where the fields were for associating OpenIDs with accounts, so I’ve configured that. My blog will now accept any of the three, although using single-factor authentication (unless I use OpenID).
Guess that’s enough for a blog, it’s not like someone can lock me out of it given I have database access anyway and the password is stored as a hash.
Needless to say though, you can expect some further improvements for things using these keys. I’ve got some other places in mind for the thing.