If you have ever seen my previous posts, you might know that I have two YubiKeys and a bunch of Linux servers.

Passwords are far from secure when comparing them with a pair of keys.

Technically not a pair of keys, just because I’m talking about asymmetric keys, so a pair of.

But if you decide to switch to Keys instead of Passwords, it’s highly possible that you will run into a trouble when you don’t know how to take care of your keys.

Most people just store them on their computers, somewhere in ~/.ssh/. This is not secure since your home directory can be accessed by any software, resulting in the potential leak of your keys.

Hardware security modules are the best choices, and the easiest and the most convenient is Yubikeys from Yubico.

Which method should I choose?

YubiKeys have multiple methods that allow you to do OpenSSH Authentication. The following table explains everything.

Method Agent OS Portability Algorithm Remarks
OpenPGP gpg-agent Windows / macOS / Linux / Android Need to change the configuration everytime you switch to a different computer. RSA / DSA / EdDSA (Ed25519) / ECDSA (P-256/384/521)
FIDO openssh Linux / Android Need to locally store a reference “private key”, much like OpenPGP smart cards. ECDSA / EdDSA with sk It is not possible to backup the private key.
PIV libykcs11 Windows / Linux Need to install YKCS11 (included in YubiKey PIV Tool and YubiKey Manager) RSA / ECDSA Currently not able to work on Android, not even 3rd-party softwares.

Today we are going to use PIV.

What you need

A computer (I’m on Ubuntu Linux, so this tutorial will be focused on operating on Linux)

It’s highly recommended to use Tails for all your critical cryptographic operations.

Of course, you need a YubiKey (2 is the best, having a backup key is never a bad idea). I’m going to use the YubiKey 5C NFC I have purchased earlier.


First you need to change the PIN, PUK, Management Key. You can learn more at here

Put simply, you need to enter the six-digit PIN whenever you need to connect to your servers.

We are going to generate the keys on the computer so that we can retain a backup. NIST P-256 ECDSA curve is the curve we are going to use today. For daily communications, 256-bit curve is enough.

openssl ecparam -name prime256v1 -genkey -noout -out private.pem

Next, we import our private key to the YubiKey using YubiKey Manager (install it beforehand please.

ykman piv keys import 9a private.pem

Enter the PIN you have set earlier.

Now we need to generate the certificate. You can ask YubiKey to generate a CSR and thus you can generate your certificate from a trusted authority or your own authority. But since this is just for authentication, self-signed is enough.

ykman piv keys export 9a public.pem
ykman piv certificates generate -s "{COMMON NAME}" -d 36500 9a public.pem
# Change {COMMON_NAME} to the CN subject you want, e.g. your name. 36500 refers to the valid days.

Note that if it says ERROR: Invalid RFC 4514 string, please change your common name to something else.

Learn more at IETF

Now everything is done, use the following command to check the PIV status.

ykman piv info

The result should look like something like this.

$ ykman piv info
PIV version:              5.4.3
PIN tries remaining:      3/3
Management key algorithm: AES256
Management key is stored on the YubiKey, protected by PIN.
CHUID: {intentionally hidden}
CCC:   No data available
  Algorithm:   ECCP256
  Subject DN:  CN=ORWTMC
  Issuer DN:   CN=ORWTMC
  Serial:      {intentionally hidden}
  Fingerprint: {intentionally hidden}
  Not before:  2023-11-05T01:41:06
  Not after:   2123-10-12T01:41:06

Now we have PEM-encoded public key, we need to convert them to OpenSSH format.

ssh-keygen -i -m PKCS8 -f public.pem

The output should start with ecdsa-sha2-nistp256


You have now configured your HSM, now let’s use it.

On Linux, make sure you have libykcs11.so, it is usually located in /usr/lib/x86_64-linux-gnu/libykcs11.so. If no, please refer to Yubico’s website for more information.

Whenever you need to connect to your server, have your YubiKey plugged in and run the following command first.

ssh-add -s /usr/lib/x86_64-linux-gnu/libykcs11.so

It will ask you for the passphrase, that’s the PIN you have set earlier. After that, connect to your server!


Check WinCryptSSHAgent, install it as well as YubiKey Manager. Then you can just connect use the included OpenSSH via PowerShell.


You have to take care of your keys. Remember that we generated our keys on our computers? Take good care of private.pem. Either print it and put in the bank’s safety deposit box or just put it in an encrypted memory card/thumb drive.