YubikeyHelp
This page is about creating your own Yubikey validation system, to complement the existing documentation.
/!\ Beware you need to change the key data in you Yubykey to be able to manage your own accounts, and doing so will prevent you from using Yubiko special services (most being available for demonstration purpose, and most being replacable, like having your own OpenID server; but you can still have a second key if you want to access Yubiko's services).
Before we go, you must understand this key is not designed to allow subscribing to different providers (like with distributing SSH public keys), but to contain full or partial credentials for one account on a particular provider. If you need to access say your own machines and your staff corporate machines via SSH and PAM+yubikey for example, then you must have two keys. As this is symetrical cryptography, both ends needs to access the secret and i guess you would not share your key between your personnal accounts and staff accounts. In this model, an account provider programs keys and distribute them among its users, which is perfectly appropriate for personnal or corporate purpose but not for a service provider. Nevertheless, your provider can act as an authentication service provider too, using OpenId for example, and then allowing sharing your account with several other service providers.
<<TableOfContents(2)>>
Understanding the Key
The yubikey hold several interresting data inside. A few of them can be modified by the user :
- public name (0 to 16 characters): the publicly advertised name of the key
- private name (6 characters): the secret name of the key
- management password: a secret used to allow changing the key data
- AES key (32 characters hexa): the secret key used to create the OTP
The public name can be whatever you want; you can, for example, set it to an empty string if you don't want to disclose to which it belongs (in case the key is lost), or use the name of your company, or even the name of the user, ... This field is often called the fixed part.
The private name can be whatever you want. It is not an important part of the security system, but can be used to identify the key uniquely. It can hold the real username for exemple (or a number, as the field is quite limited in length). It can also be used to shared the same AES key among user and still be able to distinguish the keys (to be able to revoke key rights if the key was lost, for example). This field is often called the uid part.
The management password is necessary to be able to change the data of the key. Beware not to loose it or you'll never be able to modify it (even if it seems to be possible to use the AES key instead, but i guess you would have lost it either). This field is often called the acc_code part.
The AES key is a secret number used to encrypt data and do the real security stuff. This field is often called the key part.
The key does not disclose anything inside. When you push the button (or use the double-capslock sequence in the key with no button, an OTP is generated, but there is no way to get any other output. If you have the AES key, then you're able to decrypt the OTP and validate the identity of the user. In the OTP is also included a few other interresting information:
- private name (explained above)
- counter: number of times the key was connected (pluggued to an USB port)
- use: number of OTP generated in a session (a session begin when the key is pluggued, and finish when it is removed)
But, as said, the counter and use cannot be obtained without generating an OTP and decrypting it; nevertheless, it can be used by the validation server.
Creating your own Key
Installing the Personnalization Tool
First, you need to install a library providing all the necessary functions for the personnalization tools (not packaged yet). Get the latest tarball from this page (currently 1.4) and uncompress it.
Install the needed build dependencies:
apt-get install build-essential
In the source directory:
./configure make make install
(This will install things in /usr/local, but you can pass parameters to the configure script to install it elsewhere)
Then, we can install the tools (not packaged yet). Get the latest tarball from this page (currently 0.92) and uncompress it.
Install the needed build dependencies:
apt-get install libusb-dev
In the source directory:
./configure make make install
(This will install things in /usr/local, but you can pass parameters to the configure script to install it elsewhere)
Updating Key Data
You must provide the uid parameter in hexadecimal format. Remember it is a 6 characters long string (not less, not more). You can convert a string to hexadecimal like this:
# echo -n "user01" | hexdump -v -e '1/1 "%02x"' 757365723031
You must provide the public name (fixed) parameter in either the hexadecimal or modhex format. The modhex format is a special encoding used to ensure characters sent by the key are always correctly interpreted whatever keyboard layout you use. You can convert a string to hexadecimal like this:
# echo -n "Foo Corp" | hexdump -v -e '1/1 "%02x"' 466f6f20436f7270
You can convert a string to modhex like this:
# modhex "Foo Corp" fhhvhvdcfehvidic
You can then generate a new key with the uid and fixed parameters, either with the public name in hexadecimal format:
# ykpersonalize -ouid=757365723031 -ohexfixed=466f6f20436f7270 Passphrase to create AES key: Firmware version 1.3.5 Touch level 8864 Program sequence 19 fixed:fhhvhvdcfehvidic uid:igiehgideceb key:vujkuvbhchbfihjllrlhjvennfhvfdgt acc_code:cccccccccccc ticket_flags:APPEND_CR config_flags:
or with the modhex format:
ykpersonalize -ouid=757365723031 -ofixed=fhhvhvdcfehvidic Passphrase to create AES key: Firmware version 1.3.5 Touch level 8864 Program sequence 20 fixed:fhhvhvdcfehvidic uid:igiehgideceb key:jlevvbgtbueebltnielgfcvfdldthbbd acc_code:cccccccccccc ticket_flags:APPEND_CR config_flags:
Your AES key is given in the key field. I suggest you use an empty password until you're ready for production (it is the acc_code field).
/!\ If you experience the following error:
USB error: could not claim interface 0: Device or resource busy
you can work around this problem with this tip. If it still doesn't work, you can try unbinding the device using the tip at the end of this thread.
You could also provide the AES key with the -a option, and various other options, but it is out of scope of this document. Check the ykpersonalize documentation for more information.
The Validation System
The system is split into 3 pieces:
- the Key Storage Module (KSM), in charge of storing keys data and validating OTPs
- the Validation Server, in charge of authorizing access after validating the OTP via a list of KSM and checking security policies
- the Management Server, allowing administrators to add/revoke keys and change policies, users to revoke their keys if lost, and gather accounting information
This then defines an AAA system.
In this document we will explain how to setup the two first pieces, as the third one is not necessary to get a working and secure system.
The KSM
In this tutorial, we'll use the PHP KSM server provided by Yubiko. The installation phase is properly described in this page, so this document won't duplicate information. The main problem after the systeme is ready, is to properly feed the database, which is the problem addressed here.
This KSM suggest using a file especially formated for adding many keys at once with the provided ykksm-export.pl script. For security purpose this file should be PGP signed by the user and sent to the administrator, with the content encrypted against the administrator's PGP key. This also avoid storing clear text sensitive files. This method may or may not be used, as you can simply add keys directly to the database using, for example, phpmyadmin.
Here is the meaning of each database field:
- serialNr: this is the serial number of the key, which can be found with the barcode on the pocket of your card; it is an optional and purely informational field
- publicName: the public name of the key in modhex format (would be fhhvhvdcfehvidic in the previous examples)
- created: the ISO8601 formated key creation date; it is a purely informational field
- internalName: the uid in hex format (would be 757365723031 in the previous examples)
- aesKey: the AES key in hex format
- lockCode: the key password; it is an optional and purely informational field (but better not loosing it)
- creator: the sending user PGP key number (if you used the ykksm-export.pl script); it is an optional and purely informational field
- active: boolean used to activate or suspend the key
- hardware: boolean for an unknown usage (perhaps some planned feature); it is an optional field
In the provided SQL script, the creator field is limited to 8 characters, but recent GNUPG utility return a 40 character key number, so you may want to extend it.
Considering the publicName field is modhex encoded, and the ykpersonalize tool returns modhex data, i choose to modify the program to accept modhex data for internalName and aesKey fields too. If you want to do so, use the following patch:
--- ykksm-decrypt.php.orig 2009-06-06 22:38:51.000000000 +0200 +++ ykksm-decrypt.php 2009-06-06 22:43:59.000000000 +0200 @@ -73,8 +73,8 @@ } $row = mysql_fetch_assoc($result); -$aesKey = $row['aesKey']; -$internalName = $row['internalName']; +$aesKey = modhex2hex($row['aesKey']); +$internalName = modhex2hex($row['internalName']); $ciphertext = modhex2hex($modhex_ciphertext); $plaintext = aes128ecb_decrypt($aesKey, $ciphertext);
With this patch applied, the aesKey would be jlevvbgtbueebltnielgfcvfdldthbbd in the latest example.
Your KSM is now complete. You can use curl to test your installation, as described in the testing procedure at the end of the official installation recipe.
The Validation Server
In this tutorial, we'll use the PHP validation server provided by Yubiko. The installation phase is properly described in this page, so this document won't duplicate information. The main problem after the systeme is ready, is to properly feed the database, which is the problem addressed here.
It is important to note this server is one possible implementation of a validation server. This one follows the Yubiko's specification, but it is not the only possible system. In this one a key must be associated with some kind of account defined in the SQL database in the clients table.
Here is the meaning of each database field of this table:
- active: boolean used to activate or suspend the account
- created: the ISO8601 formated account creation date; it is a purely informational field
- secret
- email: the email of the user; it is an optional and purely informational field
- notes: administrator's notes about the user; it is an optional and purely informational field
blablabla