Two-factor authentication for ownCloud using one-time passwords (OTP) from Yubikey

Yubikey NEO

NFC-enabled Yubikey NEO (source: Wikipedia)

I’ve been the proud owner of a Yubikey NEO for a couple of months now. It’s a small USB device (smaller than most USB flash drives) that identifies itself as a USB keyboard. Upon pressing the integrated button, the Yubikey generates a one-time password (OTP) following the popular HOTP standard (RFC4226), and sends it to your computer. Because it acts like a USB keyboard, the password is typed in for you. Chances are that it will be hidden by stars/dots of a password field, and you’ll never even see the password! Many applications support one-time passwords, this tutorial describes a method of using the Yubikey with ownCloud – a popular web service that allows you manage your files, contacts, and calendar in your own cloud (read: webserver). A bit like DropBox or Google Drive, but without handing your data over to big multinationals.

Download, install, and activate the plugin

This tutorial relies on the “One Time Password backend” plugin by Frank Bongrand which is currently actively maintained, and can be downloaded from the ownCloud apps archive at apps.owncloud.com. The plugin is open-source, and its development can be followed on GitHub. It’s powered by multiOTP, a library for OTP authentication by SysCo (see www.multiotp.net for more info).

Download the plugin and copy it to your ownCloud installation directory under the apps directory. Before activating it, verify the definition of user_pin in the database.xml file. It should look like this:

<field>
<name>user_pin</name>
<type>text</type>
<length>16</length>
</field>

Older versions of the plugin ship with a user_pin field of length 4, which is not sufficient for use with a Yubikey.

After having made the necessary changes, you can activate the plugin by logging in to your ownCloud installation as an administrator and going to the administration dashboard (click on your name in the top-right corner, and choose "Admin"). The plugin (app) should appear in the apps list.

Configuring your Yubikey

In order for the Yubikey to work with the plugin, the plugin needs to know the secret key (Yubico refers to it as the "AES key", others sometime refer to it as "HOTP seed", or simply "seed") using which the Yubikey was initialised. If you are already using your Yubikey with some authentication mechanism other than Yubico’s authentication service, you will probably have this key somewhere already. For example, if you’re using libpam-oath, you’ll find this HOTP seed in /etc/users.oath. In that case, skip this section.

Yubikey personalisation tool

Yubikey personalisation tool (click for larger version)

If you’re using your Yubikey to authenticate with Yubico’s authentication service, it is unfortunately impossible to extract the secret key from the device. You’ll have to re-initialise your Yubikey using Yubico’s powerful customisation tools (available for Windows, Mac, and Linux) which can be downloaded from www.yubico.com. Once you have downloaded the tools, re-initialise your Yubikey for OATH-HOTP. Make sure to copy/paste the secret key (20 bytes in hex) somewhere, because we’ll need that later! It’s up to you whether you want the Yubikey to generate 6-digit or 8-digit HOTP passwords, and you’re also free to customise the "OATH Token Identifier" (which will be added as a prefix to your one-time passwords). You might also want to re-register your Yubikey with Yubico if you’d like to continue using their authentication service.

Configuring the ownCloud app – admin

First, the plugin needs to be configured in the admin area. Choose the OTP-policy for your ownCloud installation (I use two-factor authentication, but you can also completely replace the user password by a OTP), and open the detailed configuration tab. Most settings are straightforward, but make sure to configure the following:

  • User Prefix Pin: enable this, it will be used to store the prefix ("OATH Token Identifier") of the OTPs generated by the Yubikey.
  • User algorithm: HOTP. TOTP is the time-based OTP (as used by Google Authenticator), HOTP is HMAC-based (sometimes called "event-based") and is the type of OTP generated by the Yubikey. Note that you can also configure your Yubikey NEO to function as a store for TOTP secrets – have a look at the Yubico Authenticator (YubiOATH) app for mobile phones for more information.
  • User Token Number Of Digits: set to 6 or 8, depending how you initialised your Yubikey (default: 6)
  • User Token Time Interval Or Last Event: this is a tricky one and might cause the authentication to fail (see below under "Authentication events"). If you’ve just re-initialised your Yubikey, then set this to 0. If you didn’t reset your Yubikey, you’ll have to estimate the number of OTPs it has generated already. This doesn’t have to be precise, as long as you’re not over-estimating, and are not off by more than 100. For libpam-oath users: use the number in the 5th column of users.oath. If you can’t get authentication with ownCloud to work, it might be best to re-initialise your Yubikey and set this value to 0.
  • Disable OTP with remote.php: you probably want to tick this box. Otherwise, your ownCloud sync client (which doesn’t support 2FA) will require a OTP. Hopefully, ownCloud will soon fully support OAuth (see ownCloud issue tracker – not to be confused with OATH!)

That’s all on the admin side.

Before you continue: at the time of writing, the OTP app didn’t have a reset functionality yet, so please make sure you either have an administrator account without OTP, or to have access to the ownCloud database (SQLite or MySQL) in case something doesn’t work and you lock yourself out.

Configuring the ownCloud app – user-specific

OTP at ownCloud login screen

OTP at ownCloud login screen

Every user should now be able to edit their own OTP configuration under his or her "Personal settings". Configuration is done as follows:

  • User Token Seed: that’s the secret key using which the Yubikey was initialised. However, the ownCloud app expects it as a Base-32 encoded string of 32 characters, whereas the Yubico personalisation tool provides the key hex (Base-16) encoded. Many tools exist to convert from hex to Base-32, including an online Javascript converter: www.tomeko.net/online_tools/hex_to_base32.php?lang=en. If you don’t trust the online converter (after all, you’re converting a secret key), use Google to find one for your own platform.
  • User Pin: this is the prefix to the OTP that is generated by your Yubikey. It’s easy to obtain this prefix in case you didn’t write it down: open a simple text editor (notepad, vim, nano) and press the button on your Yubikey three times, with a small pause in between the key presses. This should generate three one-time passwords. The prefix is the part of the passwords that stays the same, e.g. ubzz12345678. Put this string in the PIN field.

That’s all! It’s advisable to open a second browser on a second computer to try and login to ownCloud. Depending on your ownCloud and OTP app configuration, the login screen will now have a field for the generated one-time password. If logging in does not work, try to enable ownClouds debug log (see ownCloud documentation) to see what’s going on. If you really can’t figure it out, try resetting your Yubikey. As a last resort, you can post a comment on this article, and I might be able to help out.

Good luck!

Scan to Donate Bitcoin
Like this? Donate Bitcoin to at:
Bitcoin 14XaYybLkuB89cqnYR1Eg3bFqukpXZy4hv
Donate

Explanation of HOTP Authentication events and the event window

Based on the shared secret AES key (a.k.a. "HOTP seed" or simply "seed"), the HOTP standard describes how to generate a sequence of one-time passwords. The Yubikey has an internal counter that keeps track of the number of passwords that have been generated, and will provide the next password in the sequence upon a keypress. The authentication service (e.g. ownCloud, libpam-oath, Yubico) also has the shared secret AES key, and can generate the same sequence. The service compares the one-time password provided by the user with the OTP in the sequence it generated itself to authenticate the user.

Most implementations of authentication services (including multiOTP) have a configurable window in which they search for the OTP provided by the user. After all, accidentally pressing the button on your Yubikey should not result in the Yubikey and the authentication service getting out-of-sync. However, the window shouldn’t be too large, in order to minimise the probability of a random one-time password to work. Many implementations use a default window size of 10, multiOTP’s default is 100.

When the authentication service is set up for use with a Yubikey, it needs to know where in the sequence it should look for a user-provided OTP. This is the "Last Event" setting of the ownCloud app. If it’s set too high (i.e., beyond the counter in the Yubikey), the generated OTPs will be rejected as they are considered to have been used already. If it’s set too low (more than 100 less than the counter in the Yubikey), the authentication service will not find the user-generated OTP in the window.