How to use your YubiKey with OpenSSH to authenticate securely against servers.
I already use a YubiKey as a multi-factor authenticator to log in to some websites via WebAuthn, so I wanted to use my YubiKey for more than that. I discovered that storing SSH private keys on a YubiKey is supported, and it is a great idea.
Why store SSH private keys on a YubiKey?
- Hardware-backed security: Private SSH keys are stored on a physical device (the private key never leaves the hardware security key).
- Physical interaction: Requires a tap or touch on the key to authenticate, preventing remote misuse.
- Protection against malware, phishing, and remote attacks targeting SSH credentials.
- Optional user verification via PIN entry.
Make sure the PIN is set
To improve security, make sure a PIN is set on your YubiKey. You can configure this using YubiKey Manager.
If your YubiKey is stolen, you probably do not want someone using your SSH keys, right? While this is unlikely, improving the security of your devices is always a good idea.
Generating the FIDO2 SSH key
Let’s get to the interesting part.
There are two supported key types:
-
ed25519-sk(newer and recommended) -
ecdsa-sk(older)
ssh-keygen -t ed25519-sk -O resident -C "your_email@example.com"
Generating public/private ed25519-sk key pair.
You may need to touch your authenticator to authorize key generation.
Enter file in which to save the key (/home/user/.ssh/id_ed25519_sk):
Enter passphrase for "/home/user/.ssh/id_ed25519_sk" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_ed25519_sk
Your public key has been saved in /home/user/.ssh/id_ed25519_sk.pub
The key fingerprint is:
SHA256:1/gTzj3FHfo5m1N1pql0syI2nzVfD9opWqxpR9fT5z8 your_email@example.com
The key's randomart image is:
+[ED25519-SK 256]-+
| |
| |
| . |
| o ..*|
| S o o. =B|
| . =ooBo*|
| oB+*B=|
| =+=*.EB|
| o+*+oooB|
+----[SHA256]-----+
Key Generation Options Explained
- -t ed25519-sk or -t ecdsa-sk: Key type.
- -O resident: Creates a resident key, stored on the YubiKey itself. Enables portability across machines. Requires a PIN.
- -C "comment": Helps identify the key.
Regardless of whether the key is resident or non-resident, two SSH files are always generated: the public key and a file containing metadata for the private key.
It is important to understand that the private key never leaves the YubiKey.
Discoverable Credential (resident key)
A discoverable credential (resident key) is an SSH key whose private key is stored persistently inside the YubiKey using FIDO2.
Because the key lives on the hardware token, it is portable across machines: after reinstalling an OS or switching computers, the key can be recovered directly from the YubiKey using ssh-keygen -K.
The private key is never written to disk. Access is protected by physical possession of the YubiKey and, if configured, a FIDO2 PIN.
This model prioritizes portability and convenience, at the cost of relying entirely on the security of the hardware token.
Non-Discoverable Credential (non-resident key)
A non-discoverable credential is an SSH key where the YubiKey does not store the private key.
Instead, the YubiKey derives the key on demand using an internal secret and a
wrapped key handle stored in the local SSH key file. The private key never exists in plaintext on disk.
Both the local key file and the YubiKey are required to authenticate. Losing either one makes the key unusable. This is the default and more conservative security model used by OpenSSH.
This model prioritizes security, effectively acting as a two-factor system
(file + hardware token), and is the default behavior for OpenSSH FIDO-backed keys.
Require PIN on every key access
The -O verify-required option forces the YubiKey to require PIN verification (and usually a physical touch) for every cryptographic operation.
Example:
ssh-keygen -t ed25519-sk -O resident -O verify-required -C "your_email@example.com"
While this offers stronger security guarantees, it is often impractical for daily workflows: commands like git pull, git fetch, or IDE background Git operations would trigger repeated PIN prompts.
For this reason, this option is not used in the example above. It is better suited for rarely used or high-risk keys, such as administrative or production access.
Conclusion
I hope this guide gives you a clear understanding of how to use hardware-backed SSH keys.
These keys can be used to securely connect to servers using a YubiKey, and they can also be integrated into your Git workflow by adding the public key to platforms like GitHub or GitLab.
Top comments (0)