My Yubikey implementation
Today we’re going to continue our discussion on the Yubikey from Yubico. I received mine in the mail a few weeks ago and had the opportunity to play around with the device a bit. Many people were attracted to the Yubikey because of it’s cool, tiny keyboard - so they ordered them. When it arrived they plugged it into their computers and touched the green surface which then spits out a 44 character encrypted one time password. That’s all nice and very cool but now what? How can this very innovative security token that is a tiny USB keyboard be put to good use? I, therefore, devised a way to prove that this cool token can really deliver. My plan was to customize this blog’s “admin logon” and incorporate the Yubikey authentication as an added layer of security.
Good news, Yubikey authentication is open source! This means that developers are able write code both on the client side as well as the server side to leverage the Yubikey in their own environments. There are not too many options for do-it-yourself hardware authentication solutions! Yubico offers sample code in a variety of languages that can help you get going. You can also authenticate against Yubico’s authentication server, hosted by them. This would come in handy for companies that plan on implementing their own server authentication, however, are not there yet and would like to test their client side code. In my case I decided to authenticate against Yubico, since it’s simpler and quicker. There is a downside to this approach that is worth mentioning. If I wanted to log onto my blog’s “admin panel” and for some reason the Yubico authentication server was down, I would be locked out of my blog’s admin panel.
This blog uses Wordpress, the popular open source PHP blogging software. Modifying the admin logic to include the Yubikey as a 2nd level of authentication was very easy. I utilized the code written for PHP. First, I dropped in the Yubico class on my server. I then added in some code to the wp-login.php file.
Here is the function that calls the Auth_Yubico class:
function verifyYubikey ($token) {
global $error;
$yubi = &new Auth_Yubico(’77′,’5dFRPaFvjBvwiiB023ZWu4Qb++U’);
$auth = $yubi->verify($token);
if (PEAR::isError($auth)) {
$yub_error = $auth->getMessage();
$error = __(’<strong>ERROR</strong>: ‘. $yub_error);
return false;
} else {
return true;
}
}
Here is where I modified the logic for logging on in the wp-login.php file.
if (verifyYubikey($user_yub) && wp_login($user_login, $user_pass, $using_cookie)) {
I verify the yubikey string prior to verifying my static password so people can try it out by putting in a password and see what errors are returned back from Yubico’s authentication server; more on that shortly…
So, how does the Yubikey work? We talked about asymmetric encryption in a prior post. Each Yubikey contains a unique private key that encrypts some data, turning it into the encrypted OTP (One Time Password). The Yubikey uses a conversion scheme to ASCII, which they call mod-hex. The 44 character blob is made up of 12 characters plus the 32 character OTP. The first 12 characters never change; they are your Yubikey’s unique id. So you have the 48 bits plus an AES encrypted 128 bits sent over to the authentication provider (in my case, the Yubico server). Yubico then does a lookup with my unique 12 characters and pulls the “public” key to do the decryption. Now, if the authentication side is able to decrypt this blog then you are successfully authenticated. After decryption you have 128 bits of cipher text. Besides containing your unique id, the cipher text also contains some additional useful information about how your Yubikey has just been used. For example, the time-stamp of when the OTP was generated is included, as well as a session “use counter” showing how many times you generated an OTP. This information can be used to thwart some sneaky phishing attacks. Another thing to note is that your secret AES key in the Yubikey is never able to be read out; nothing you can do to the device can force it to give you it’s secret key. All in all, this hardware solution is extremely secure.
Below are two Yubikey passcodes generated from my Yubikey that I used to authenticate myself when creating this post. I highlighted the first 12 characters, my unique serial number indentifying my Yubikey. You can copy and paste the string in the Yubikey field on my admin page and then type in anything for the static password (logic for verifying Yubikey is done prior to the static password as you can see in the PHP code above).
jdteklknnhcffbfgjebejhbbgnrtrevingnldlctiulj
jdteklknnhcfnfidtedkcelbrkvngurddrclghnidgfh
To make sure the responses come from Yubico, they offer you the ability to create an id with a shared key. When you authenticate, there is an extra field returned to which you can apply a signature algorithm. To apply this algorithm you use your shared key to validate that the response actually came from Yubico. In the code of the “verify method” above I included my id of 77 and the shared key that was assigned to me. I just tried changing the shared key by adding a “1″ to the end of that string and wasn’t alerted that my signature algorithm failed; which it should have done. Perhaps I’m doing something incorrectly; feel free to comment. I’d like to say thank you to Simon from Yubico who was responsive to the questions I posed. Yubico also set up a forum where you can learn more about Yubikey.










June 5th, 2008 at
[...] post on my Yubico [...]
July 9th, 2008 at
Very cool, I’m also planning to use Yubikey as a voting mechanism on my rating site. I heard the price will come down as the production volume grows up quickly.
July 28th, 2008 at
A great post, this has been very helpful in my implementation of the yubikey PHP class. I do have a bit of a correction, however. The yubikey, to my understanding, uses symmetric shared-key encryption, rather than using the asymmetric public/private key model. This is still secure, because there is nothing you can do to induce your yubikey to spit out the key, which is only shared under lock-and-key over at the yubico server side. Yubico has opted for symmetric encryption because of simplicity - as explained in this post: http://forum.yubico.com/viewtopic.php?f=6&t=21 As Steve Gibson notes in episode 154 of Security Now, the computation power of the yubikey would have to be much greater in order to get asymmetrically encrypted text out of it, which isn’t really feasible.