My KeyChain 🔑

Table of Contents

Four months ago, I received two Yubikey 5C NFC devices and a Yubikey 5C Nano. Once I had them open, I started reading the official documentation for knowing how to add a gpg key to them.

After delving deeper into the Yubico documentation, I discovered that YubiKeys support numerous protocols, many of which I became interested after knowing how they work and what they solve.

Three hours later, I finally understood what YubiKeys can and cannot do, as well as the various protocols they support. However, I encountered some challenges:

  • The official documentation is not “begginer” friendly; it spans multiple pages with different domain names, lacking a comprehensive and straightforward explanation of the different capabilities.
  • Youtube videos only cover specific functionalities like FIDO and two-factor authentication, without providing a complete overview of the keys capabilities.

This article aims to provide a brief overview of what YubiKeys support, how they function, and the protocols I use to secure my passwords and accounts.

Understanding the Yubikeys

Yubikey interfaces

How your computer sees the yubikey depends on the protocols you’re enabling on the key. It can be:

  • A keyboard (HID): When the yubikey has enabled the OTP protocol, you have access to 2 slots, one that is enabled with one touch and the other that is accessed with one long touch (4 seconds or more).

    Of course, if your computer sees the yubikey as a keyboard it means that it has to “type” something when you click the yubikey (in other words, if you activate the slot 1 with a simple touch it should return something, and if you activate the slot 2 with a long touch it should type another thing).

    You can configure each slot for using Yubico OTP, OATH HOTP (altough this is legacy, use the CCID OATH instead), static password and challenge-response) you can read more here. This means that, if you configure the first slot as “static password” an you click once the yubikey, it will paste the password in your computer.

  • A HID FIDO Device: It is seen as a device that supports FIDO (a protocol which enables you no password authentication, we’ll explain it latter). The supported protocols are:

    • FIDO U2F (you can see it as FIDO version 1).
    • FIDO2 (as the name says, FIDO version 2)
  • A CCID (SmartCard) device: It saves private and public keys, it supports:

    • OpenPGP: For saving GPG keys.
    • PIV (Personal Identity Verification): Save RSA and elliptic curve keys inside the yubikey (I won’t use it for SSH since I use the gpg keys as my ssh keys).
    • OATH: All the authentication methods from the OpenAuthentication organization. It supports the methods:
      • TOTP: For two factor authentication (I’ll use it for 2FA).
      • HOTP: More or less like TOTP but less secure since it doesn’t depend on time.

    Each one of the three smartcard supported standards have different slots (this means that OpenGPG has 3 slots, one for each key (signing, encrypting and authentication), PIV has 20 slots (so, you can save 20 ssh keys) and OATH has 32 slots (so you can save 32 TOTP passwords)).

    Each slot has different PUK and PIN passwords (for adding/deleting/accessing new keys inside the slot), so you’ll have one PIN for OpenPGP, another one for PIV, etc.

If you enable one of the protocols the interface will appear. This means that if you have enabled OTP, FIDO2 and PGP, your computer will see the yubikey as 3 devices (HID, FIDO-HID and SmartCard).

Now that you’ve a global overview of the different standards the yubikey supports, you can read more details of each one inside the official documentation

How I changed my security model with Yubikeys.

The before security model was the following:

Security Model Before Yubikey

As you can see, I use a password manager that uses my personal gpg key that lives on my pc/laptop/phone (was shared like a caveman with a simple copy and paste to the device, no sync software like syncthing).

The 2FA passwords live inside the same password manager, with pass-otp.

I have one ssh key for each one of my devices, and I don’t copy paste the three keys and add it to the server, there are days that I’ve copied only one ssh key, which means that If I lose this device I couldn’t access the servers. I know that I could do backups, or sync the ssh file with syncthing between multiple devices, but I wanted to only have one key where my private key is saved in a safe place.

Things that annoys me:

  • If someone brute-forces my gpg files I am screwed, and the worst part, they could get my keys from three different devices! phone, laptop or pc.
  • The same with ssh keys. They can brute force them (and some of them were created without a password :) ).
  • Losing ssh keys.
  • Having multiple ssh keys.
  • TOTP passwords live on the same place as the “normal” passwords, so, if someone breaks my gpg keys they can access all the accounts since they’ll have the OATH token too!.

After configuring my yubikeys, my security model looks like this: Security Model After Yubikey

What I’ve fixed:

  • Remove brute-force attack on .gpg files (they-re not saved on my computer).
  • Remove brute-force attack on .ssh files.
  • Losing ssh keys: Now I will loose the ssh keys if I loose my 3 yubikeys.
  • Having multiple ssh keys (now I have one for everything, but I can generate “dummy” ones if I would like to and save them inside the PIV slot).
  • TOTP passwords are now inside the yubikey, which means that they’re in a different place than my passwords and they live in a more secure space.

And after using this model for a week I can see that I won commodity on some places, like for example:

  • FIDO2: I can go to a computer of someone that doesn’t have pass, and logging to my fido2 accounts without a password, only with my yubikey pin and a touch!

Setting up my password manager (GPG)

As I said before, I use my yubikey for saving my GPG keys (encrypt, auth and signing), and I use pass for encrypting all my passwords. Since this is a deep rabbit-hole, I will only leave some links for the readers that want to learn more.

First, you have to understand GPG (which is difficult, it’s a monster standard), I recommend you:

Then, once you understand GPG, you can configure your yubikeys. I would recommend this guide by 402 payment required, it is pretty good.

Setting up two factor authentication (OATH)

For enabling OATH is super-easy, just download the app (it’s a flutter app, so you can use it on desktop and mobile), and add accounts to it.

Be aware that you can only set 32 accounts. Since the OATH module has only 32 slots!.

Setting up passwordless authentication (FIDO2)

FIDO2 is super-easy to setup too! You have to go to the account webpage that supports it and enable it. Right now not a lot of pages are compatible, but my github and gitlab account supports it, so not too bad.

[July 2024 update] Setting up AGE for nixos secrets

Note: If you are not using NixOS and/or don’t know what is AGE maybe you will not understand anything below that, I didn’t want to explain all this deep-rabbithole in one post, this are more mental notes than good writting.

I use agenix for management my secrets in NixOS, allowing me to keep my passwords inside an encrypted file and decrypt them at runtime. The problem is that, if the secrets are encrypted we should decrypt them at some point for reading the contents, but, when I’ve just booted my PC and I need the contents of an encrypted file (concretely the hash of my user password) for log-in, and I have to be loged-in to decrypt a secret (because it’s encrypted with gpg and the gpg-agent starts when the user has logged in) we have the chicken and the egg problem.

That’s why initially I used ssh keys (saved inside the filesystem of the pc/laptop) for encrypting/decrypting. The private keys shouldn’t have a password because of the problem described before. I don’t mind that the private keys are unencrypted on my pc (given that, if someone has entered my pc/laptop, I will probably already be compromised), but I want to encrypt my secrets with only one key, since I use different devices.

Finally I discovered agenix-rekey, which allows me to save all my secrets with a given key, but then at build time it re-encrypts the contents with the key of the host it’ll run on. So I can have my secrets encrypted with the ssh private keys that live on my yubikeys and have “non-important” ssh-keys for each host I want to build! And allowing me to have the ssh private keys that “matters” inside my 3 yubikeys, making it nearly impossible to lose the ability do decrypt my secrets.

For doing that, of course I have to use the PIV’s slot, since it allows to save the SSH keys that age uses.