Disclosure: As an Amazon Associate, CardWise earns from qualifying purchases at no additional cost to you. This does not affect our recommendations.

YubiKey PIV for SSH Authentication — Setup Walkthrough

Last updated: August 2026

Your SSH private key never has to live on disk. With a YubiKey 5 NFC, the RSA or ECC private key is generated inside the hardware security module and cannot be extracted. Every SSH authentication request is signed inside the YubiKey, and the signed response is sent to the server. Even if your laptop is compromised, the attacker cannot steal your SSH key.

This guide walks you through the complete setup: from a fresh YubiKey to SSH-ing into a server.

What You Need

PIV Key Slots Overview

The YubiKey PIV application has several key slots. For SSH, we use the Authentication slot (9a):

SlotPIV IDTypical Use
Authentication9aSSH, login, general authentication
Digital Signature9cDocument signing, code signing
Key Management9dEncryption, key exchange
Card Authentication9eCard auth (less common)
Slots 82-9582-95RSA/ECC (YubiKey 5.3+ firmware)

Step 1: Set PIV PIN, PUK, and Management Key

A fresh YubiKey ships with default PIV credentials. Change them immediately:

# Set the PIN (default: 123456, min 6 digits, max 8 digits)
ykman piv access change-pin --pin 123456 --new-pin YOUR_NEW_PIN

# Set the PUK (default: 12345678, min 6 digits, max 8 digits)
ykman piv access change-puk --puk 12345678 --new-puk YOUR_NEW_PUK

# Set the management key (default: 010203040506070801020304050607080102030405060708)
# Option A: Keep it derived from PIN (recommended — no separate key to remember)
ykman piv access set-management-key --protect --pin YOUR_NEW_PIN

# Option B: Set a custom management key (hex, 24 bytes)
ykman piv access set-management-key --management-key 010203040506070801020304050607080102030405060708 --new-management-key YOUR_HEX_KEY
Write down your PIN, PUK, and management key. If you forget the PIN and PUK (3 retries each), the PIV application locks. You need the management key to reset PIV, which erases all keys and certificates.

Step 2: Generate the PIV Key Pair

Generate an ECC or RSA key in slot 9a. The private key is generated inside the YubiKey and never leaves it.

# Option A: ECC P-256 (recommended — faster, smaller keys)
ykman piv keys generate --algorithm ECCP256 --pin YOUR_NEW_PIN 9a

# Option B: RSA 2048 (wider compatibility)
ykman piv keys generate --algorithm RSA2048 --pin YOUR_NEW_PIN 9a

Step 3: Create a Self-Signed Certificate

SSH does not validate the certificate chain, but OpenSSH needs a certificate to extract the public key. Create a self-signed one:

ykman piv certificates generate --subject "SSH:[email protected]" --pin YOUR_NEW_PIN 9a

Step 4: Export the SSH Public Key

# Extract the SSH public key from the PIV certificate
ssh-keygen -D /usr/lib/x86_64-linux-gnu/libykcs11.so > ~/.ssh/yubikey.pub

# Or on macOS:
ssh-keygen -D /usr/local/lib/libykcs11.dylib > ~/.ssh/yubikey.pub

# Or using ykman directly:
ykman piv export-ssh-key 9a > ~/.ssh/yubikey.pub

Copy the contents of ~/.ssh/yubikey.pub to the server's ~/.ssh/authorized_keys.

Step 5: Configure SSH to Use the YubiKey

Option A: PKCS#11 (universal, works with all OpenSSH)

# Add the YubiKey to ssh-agent
ssh-add -s /usr/lib/x86_64-linux-gnu/libykcs11.so

# Or on macOS:
ssh-add -s /usr/local/lib/libykcs11.dylib

# Test:
ssh [email protected]

When you connect, you will be prompted for your PIV PIN. Enter it once, and the agent caches it for subsequent connections.

Option B: yubikey-agent (daemon, auto-starts with macOS/Linux)

# Install
brew install yubikey-agent   # macOS
# Or: go install filippo.io/yubikey-agent@latest

# Configure
yubikey-agent --setup

# Add to ssh config
echo "IdentityAgent ~/Library/yubikey-agent/agent" >> ~/.ssh/config

yubikey-agent is a dedicated SSH agent that automatically loads your YubiKey PIV keys on startup. It prompts for PIN once per session.

Option C: FIDO2 resident key (OpenSSH 8.2+, no PIV needed)

# Generate a FIDO2 resident key directly
ssh-keygen -t ed25519-sk -O resident -f ~/.ssh/id_ed25519_sk

# Copy to server
ssh-copy-id -i ~/.ssh/id_ed25519_sk.pub [email protected]

# Connect (YubiKey will prompt for tap)
ssh -i ~/.ssh/id_ed25519_sk [email protected]

This method uses FIDO2 instead of PIV. No PKCS#11 library needed, but requires OpenSSH 8.2+ on both client and server.

Multiple YubiKeys

If you have a backup YubiKey (recommended), generate keys on both and add both public keys to authorized_keys. A second YubiKey 5C NFC makes an ideal backup — different USB form factor so you are covered for both USB-A and USB-C ports. Check Price on Amazon

# Key 1
ykman piv export-ssh-key 9a >> ~/.ssh/authorized_keys

# Switch to backup YubiKey, then:
ykman piv export-ssh-key 9a >> ~/.ssh/authorized_keys

Each YubiKey has its own key pair, so the public keys are different.

Troubleshooting

ProblemSolution
"device not found" when running ykmanEnsure YubiKey is inserted. Try a different USB port. Check ykman list
"wrong PIN" after 3 attemptsPUK can unlock: ykman piv access change-pin --puk YOUR_PUK
Both PIN and PUK blockedReset PIV: ykman piv reset (erases all keys)
SSH prompts for password, not YubiKeyCheck ssh-add -l to verify the key is loaded in agent
libykcs11.so not foundInstall yubico-piv-tool: brew install yubico-piv-tool or apt install libykcs11

Security Best Practices

YubiKey Models Compared for SSH

FeatureYubiKey 5 NFCYubiKey 5C NFCFeitian BioPass
PIV (SSH via PKCS#11)YesYesNo
FIDO2 (SSH via ed25519-sk)YesYesYes
OpenPGPYesYesNo
NFCYesYesYes
USBUSB-AUSB-CUSB-A
BiometricNoNoYes (fingerprint)

YubiKey 5 NFC — Best for SSH with PIV support. Check Price on Amazon

YubiKey 5C NFC — USB-C variant for modern laptops. Check Price on Amazon