ieatpizza
ieatpizza

Reputation: 484

How do I decode a Yubikey OTP token?

I'm trying to figure out how to build a feature to authenticate with a Yubikey OTP.

I want to self-host my own authentication service, without relying on the Yubikey API.

I've looked through their example yubikey-ksm project, trying to figure out the format of the Yubikey requests, so I can try to build my own. However, it seems like their example is looking up the token's AES key in a key database. I'm not really sure where this key comes from, since there is no step to install an AES key when setting up a new Yubikey.

My current understanding of the process (please correct if anything is wrong):

  1. Take the first 12 characters of the OTP; this is the token ID, as well as the last 32 characters; this is ciphertext.

  2. Somehow get the AES key associated with this token ID (but where??) as well as an "internal name".

  3. Decrypt the 32 character ciphertext with AES128 in ECB mode using the key from step 2 and 0x00000000000000000000000000000000 as an IV.

  4. Check that the first 12 characters of the plaintext matches the "internal name" from step 2 and that the CRC of the plaintext is correct.

  5. If step 4 is correct then the key is validated. The next 4 characters are the counter, the next 8 characters are a timestamp, and the next 2 characters are a use counter.

Where does this AES key and "internal name" from step 2 come from? And, given there's no secure way for the remote server and the Yubikey to negotiate a new AES key, how is this secure from an attacker obtaining the AES key in the same way a legitimate site owner would need to obtain it to validate the keys?

Upvotes: 2

Views: 1278

Answers (2)

U. Windl
U. Windl

Reputation: 4391

The "AES key" is a shared secret. My guess is that Yubico knows the AES key of your key when shipped (so their validation server can work). However there's no way to find out your AES key AFAIK (other than brute force).

So you have two options:

  1. Use one of the sample data found to test your software
  2. Reprogram your Yubikey so that you know that data you configured (I used that way, and my key has the funny ID filefilefile now.

I wrote some test implementation, and when creating a new software key with random data, the result might be this:

key_data=YubiKey::OTP::Core(type=13, instance="filefilefile", public_id=47a347a347a3, private_id=0c17ca9ec613, use_counter=1, timestamp=84a4|52, session_counter=0, rnd_number=0x3796, CRC=0xccde, time=6661187.86, ekey=ef743110d8e779df94d629f39a4de9c8)

Upvotes: 0

Florent
Florent

Reputation: 106

My understanding of yubicloud's webpage ( https://www.yubico.com/products/yubicloud/ ) is that you basically have 2 models of OTP validation with your yubikeys:

  • Either you use the built-in AES key in your device, which is known by the Yubikey (yubicloud) servers (so web apps can authenticate you using their API);
  • Or you generate you own AES key, and provide it both to your authentication server and your Yubikey, and setup you Yubikey so that it uses this custom key.

Regards

Upvotes: 1

Related Questions