YubiKey is a type of hardware security key sold by Yubico.

  • It is recommended that you keep at least one backup key.
  • Change all default PINs.
  • Turn off any features you don’t use in YubiKey Manager.

What to Buy

I recommend buying YubiKey 5C NFC so that you can use FIDO2 (which doesn’t support NFC yet) with your phone easily. It’s a good idea to keep another one at home or in your PC. If you are extra paranoid, buy a third one and keep it at a relative/friend’s house. You might not need all features (e.g., TOTP, PIV, OpenPGP) available in the main lineup, especially for backup keys, so also consider buying the cheaper Security Key variants.

Setup

PIN

Make sure no PINs are unset or left as default:

  • Configure FIDO2 PIN via either the YubiKey Manager or ykman utility. There is no default PIN for FIDO2. If you have set a PIN and notice that enrolling your key at a website doesn’t prompt for a PIN, the website might only support FIDO U2F, which does not support PIN.
  • Configure PIV PIN (used for using PIV) and PUK (used for unblocking PIN when it’s entered wrong too many times). The default PIN is 123456 and 12345678 respectively. Note that you can’t unblock the PUK without resetting PIV. Management key doesn’t matter that much if the key is for personal purposes only.
  • If you use OpenPGP keys, follow the next section to save them to your YubiKeys.

OpenPGP

We can use GPG to configure YubiKey’s OpenPGP functionality. This guide assumes that your private keys (primary & subkey) are still stored on the computer. Before doing anything with the GPG key, make sure to make a backup with gpg --output key.gpg --export-secret-key <uid>. Store it on multiple external drives, or use other methods as you may see fit.

Note that there are two pins for OpenPGP: User PIN (default 123456) used for accessing the key and Admin PIN (default 12345678) used for configuring the key. Run gpg --card-edit and follow the steps below:

  • admin: Enter admin mode to access more commands.
  • kdf-setup: Enable KDF hashing for PIN authentication. You must do this before adding any PGP keys to YubiKey, otherwise you’ll have to factory-reset before enabling this option.
  • uif [1|2|3] permanent: Require touching key for signing, authenticating, and encrypting. Invoke this command for 1, 2, and 3. Note if you ever want to turn this off without factory resetting, use on instead of permanent.
  • forcesig: require PIN for all actions (i.e., don’t cache)
  • passwd: Use this command to change both user and admin PINs.
  • Add more information to your key as you see fit, e.g., key URL, name, salutation, etc.

Now we can save the key to our YubiKeys. Run gpg --edit-key <uid>, where <uid> should be replaced with the email of your key. For each subkey Sign, Encrypt, and Authenticate that you want to export (note that you can only export one of each), run key <subkey-index> and keytocard in gpg. gpg will warn you that it will delete keys upon save, so just keep that in mind—==use quit as opposed to save== if you have another key to configure.

Our goal is to keep primary key offline and keep subkeys in Yubikeys. When you are done configuring all YubiKeys, double check you have a copy of your public and private keys in backup storage, then run gpg -K --with-subkey-fingerprint to list private keys with subkey fingerprints, and delete all of them with gpg --delete-secret-keys <uid> <subkey1-fpr>! <subkey2-fpr>! <subkey3-fpr>!. Import your previously saved public key, and run gpg --card-status to let GPG know that the subkeys are available in your YubiKey.

Once you’re done configuring OpenPGP, your gpg output should look similar to the following (note sec# which means primary key is currently offline/unusable, and ssb> which means the subkey is available on a smartcard, i.e., the YubiKey):

PS C:\> gpg -K --with-subkey-fingerprint
[keyboxd]
---------
sec#  ed25519 2024-05-23 [C]
      5416EDF824D8DC2F5316DEAECF937A6F9BEA0292
uid           [ultimate] Zhenkai Weng <hello@zhenkai.dev>
ssb>  cv25519 2024-05-23 [E] [expires: 2029-05-23]
      2B4646A976901E4D53B358A43AEB78B87852DED0
      Card serial no. = 0006 28xxxxxx
ssb>  ed25519 2024-05-24 [S] [expires: 2029-05-23]
      86FA4CF80FFE35967B3360590A8CBB63A6F8BDCB
      Card serial no. = 0006 28xxxxxx
ssb>  ed25519 2024-05-24 [A] [expires: 2029-05-23]
      EB9D2E33BE11D74FDE3F60FF735FFE0BC9D48EE4
      Card serial no. = 0006 28xxxxxx