rlm_yubikey

Arran Cudbard-Bell a.cudbardb at freeradius.org
Tue Mar 12 18:31:44 CET 2013


What is Yubikey?
-----------------------

It's another OTP solution.

Why use it?
----------------

* smsotp is rediculously insecure
* otp clients on mobile phones can be compromised
* RSA tokens suck.

I'll expand on the RSA stuff a bit. Here's why RSA sucks:

* You need to install and maintain a special RSA Appliance just to try out the system.
* RSA tokens have a limited lifespan, once the battery runs out the token is useless, you need to get it replaced by RSA.
* RSA tokens use pre-generated token seeds. These become cryptographically useless if either your servers or RSA servers are compromised [http://arstechnica.com/security/2011/06/rsa-finally-comes-clean-securid-is-compromised/].
* They're not user friendly. Users have to transcribe the numbers and complete authentication before the code changes (something that a suprising number of users seem to find impossible). 
* The tokens often get out of sync with the RSA server.
* The tokens get scratched to the point you can't read the numbers off the screen.

The yubikey guys came up with a different solution:

* You still have physical token, but its powered by the USB port.
* You set the encryption keys (write only), and instead of forcing users to type in a number, it just acts as a HID. When you tap the little button on the face, it enters the OTP string for you.
* Instead of using a seed and mutating it synchronously on the token and server, it uses a fixed encryption key to encrypt validation data in the password string. The encrypted data includes replay counters to stop tokens being reused.

Although the tokens are kinda expensive $15-$25 if you need a really secure OTP system probably worth giving them a trial.


Why am I going on about Yubikey ?
-----------------------------------------------

Just finished an rlm_yubikey implementation. 

I know there were a couple of implementations on the net already, but they were pretty poor.

There was a C one:

https://code.google.com/p/freeradius-yubikey-module/

But... Well... asside the code... in general... it used its own weird config system for recording keys, values and replay data, so couldn't integrate with any of the dynamic language modules, sql or ldap.

There's also a perl one floating around somewhere, but eww, perl.

Here's the config for the new one.

The yubikey authorize method acts like PAP, but is more diserning and will only set Auth-Type if it finds a User-Password value which is very likely to be yubikey OTP data.

For basic testing:

authorize {
	update control {
		Yubikey-Key := "0x45a9405b05e956c10257c58dd149c6c4" (the secret key that you set on the token)
	}
	yubikey
}

authenticate {
	Auth-Type yubikey {
		yubikey
	}
}

You need to handle storing counter values, but it's not exactly hard if you understand what's going on, and pretty site specific anyway. The module will look for a Yubikey-Counter value in the control list, and make sure it's less than the current counter value.

Anyway, here's the default config. I'll probably add some sqlite stuff at some point to allow basic replay detection (or if anyone else wants to do that, it'd be appreciated).

This is available in FreeRADIUS 3.0 only.

https://github.com/FreeRADIUS/freeradius-server/blob/master/src/modules/rlm_yubikey/rlm_yubikey.c

-Arran

#
#  This module decrypts and validates Yubikey static and dynamic
#  OTP tokens.
#
#  The module itself does not provide persistent storage as this
#  would be duplicative of functionality already in the server.
#
#  Yubikey authentication needs two control attributes 
#  retrieved from persistent storage:
#    * Yubikey-Key     - The AES key use to decrypt the OTP data.
#                        The Yubikey-Public-Id and/or User-Name 
#                        attrubutes may be used to retrieve the key.
#    * Yubikey-Counter - This is compared with the counter in the OTP
#                        data and used to prevent replay attacks.
#                        This attribute will also be available in 
#                        the request list after successfull
#                        decryption.                    
#
#  Yubikey-Counter isn't strictly required, but the server will
#  generate warnings if it's not present when Yubikey.authenticate
#  is called.
#
#  These attributes are available after authorization:
#    * Yubikey-Public-ID  - The public portion of the OTP string
#
#  These attributes are available after authentication (if successfull):
#    * Yubikey-Private-ID - The encrypted ID included in OTP data,
#                           must be verified if tokens share keys.
#    * Yubikey-Counter    - The last counter value (should be recorded).
#    * Yubikey-Timestamp  - Token's internal clock (mainly useful for debugging).
#    * Yubikey-Random     - Randomly generated value from the token.
#    * Yubikey-Trigger    - How the Yubikey was triggered
#                           ('keyboard' or 'button'). 
yubikey {
	#
	#  The length (number of ascii bytes) of the Public-ID portion
	#  of the OTP string.
	#
	#  Yubikey defaults to a 6 byte ID (2 * 6 = 12)
	#id_length = 12
}



More information about the Freeradius-Users mailing list