May 11, 2020

SSH login with yubikey using PIV


This article will take you through setting-up a yubikey to hold your SSH private key. It assumes that you have a PIV-enabled yubikey:

PIV, or FIPS 201, is a US government standard. It enables RSA or ECC sign/encrypt operations using a private key stored on a smartcard (such as the YubiKey NEO), through common interfaces like PKCS#11.

PIV is primarily used for non-web applications. It has built-in support under Windows, and can be used on OS X and Linux via the OpenSC project.

In a later post we will repeat the same exercise, this time with OpenPGP.

Device setup

First, nwe need to install some software: there is a CLI and a UI version and the detailed instructions can be found here.

In this article we will go for the CLI on Ubuntu:

sudo apt-add-repository ppa:yubico/stable
sudo apt update
sudo apt install yubikey-manager
sudo apt intall yubico-piv-tool
sudo apt install ykcs11

Change PIN, PUK

ykman piv change-pin
ykman piv change-puk

Note: The default PIN/PUK are 123456 and 12345678

Generate a management key

Generate a random management key:

dd if=/dev/random bs=1 count=24 2>/dev/null | hexdump -v -e '/1 "%02X"'

and set id:

ykman piv change-management-key -n <key-from-above>

Recover from a blocked PIN

If a wrong PIN is entered 3 times it will become blocked. To recover it use:

ykman piv unblock-pin

and authenticate with the PUK.


If you have lost access to your PIN and PUK the only way to recover is to completely reset the PIV functionality, which will erase any keys or certificates stored on the device and set the default PIN, PUK and Management Key. This will only affect the PIV portion of your YubiKey, so any non-PIV configuration will remain intact.

ykman piv reset

Setup PIV for SSH

  1. Locate on Ubuntu it is located in /usr/lib/x86_64-linux-gnu/
  2. Geenrate a key: yubico-piv-tool -s 9a -a generate -k --pin-policy=once --touch-policy=always --algorithm=RSA2048 -o public.pem (will ask for your management-key)
  3. Create a self-signed cert: yubico-piv-tool -a verify-pin -a selfsign-certificate -s 9a -S '/CN=ssh' --valid-days=3650 -i public.pem -o cert.pem (will ask you to enter PIN, then touch the yubikey)
  4. Import the certificate: yubico-piv-tool -k -a import-certificate -s 9a -i cert.pem (will ask for your management-key)
  5. Export the public key: ssh-keygen -D /usr/lib/x86_64-linux-gnu/pkcs11/ -e, and copy it to your .ssh directory, e.g. ``~/.ssh/`
  6. Copy the ssh-key to your server: ssh-copy-id -f -i ~/.ssh/ <user>@<server>
  7. Check the key’s status: yubico-piv-tool -a status
  8. Log-on: ssh -I /usr/lib/x86_64-linux-gnu/ sven@srv-3
  9. Add the key to your ssh agent: ssh-add -s /usr/lib/x86_64-linux-gnu/ (note: this may cause some errors if on the same time you have gpg-agent running)

Content licensed under CC BY 4.0