What is a One-Time Password (OTP)?
A one-time passcode or password (OTP) is a code that is valid for only one login session or transaction. An OTP is typically sent via SMS to a mobile phone, and they are frequently used as part of two-factor authentication (2FA). The NIST organization has recently deprecated SMS as a weak form of 2FA and encourages other approaches for strong 2FA. (See Yubico Glossary)
There are two main components in a Yubico OTP validation server.
The Key Storage Module (KSM), and the Validation Server. Both of these are required for OTP validation, and either one can be replicated for redundancy.
Key Storage Module (KSM)
The KSM is the keeper of the individual YubiKey secrets. For each Yubico OTP credential in use by the system, there exists an AES key, as well as a private identity. These are associated with the public ID of the credential, and must be kept secret. Using these secret values an OTP can be decrypted and validated, which ensures the authenticity of the OTP. More precisely, that a given OTP was generated on a specific YubiKey. Once decrypted and validated, the KSM extracts the counters and timer data from the OTP.
Any time a new Yubico OTP credential is added to the system, the secret values need to be added to the KSM. You can optionally use a YubiHSM USB device to keep these secret values secure, even in the event of a KSM server becoming compromised. Due to the increased safety gained by using a YubiHSM, this is the approach we recommend.
While the KSM decrypts and validates the authenticity of OTPs, it does not keep a record of which authentic OTPs are invalid due to previous use. To ensure that each OTP can only be used once, and that older OTPs are invalidated once a later OTP is used, we have a Validation Server. The Validation server keeps track of the last seen counter values for each YubiKey credential, and enforces that these continue to increment for each new OTP. The purpose of this is to prevent replay attacks from being possible.
Apache, PHP and MySQL should be installed first. Due to the packet dependency of yubikey-ksm and yubikey-val, a MariaDB server cannot be used.
Then, two databases should be created (ykksm and ykval) with associated users (ykksm_reader and ykval_verifier).
For this guide we start with a fresh installation of Ubuntu Server 16.04 (TLS). Because we will be using the latest versions available of Yubico software, we add the Yubico PPA:
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:yubico/stable
sudo apt-get update
We will be programming a YubiKey for testing purposes, and for that we will need to install ykpersonalize:
sudo apt-get install yubikey-personalization
Installing the KSM
For the Key Storage Module we will use yhsm-yubikey-ksm, which is part of the python-pyhsm project. This server can be used with or without a YubiHSM device. First, we install the required packages:
sudo apt-get install yhsm-yubikey-ksm
Now, as we will not be using a YubiHSM for in this guide, we need to create a master key for encrypting Now we need to create a master key for decrypting Yubico OTP secrets with, and since we will not be using a YubiHSM in this guide, we do so by creating a plaintext file:
sudo mkdir -p /etc/yubico/yhsm
sudo nano /etc/yubico/yhsm/keys.json