OpenPGP keys on a smartcard, YubiKey or Nitrokey with GnuPG
An OpenPGP card keeps your secret keys inside a small chip that never lets them out. Your computer sends data in, the card signs or decrypts it, and malware on the computer cannot copy the key. The safe setup is: keep the primary key offline as a backup, and put three subkeys (sign, encrypt, authenticate) on the card for daily use.
What an OpenPGP card is
“OpenPGP card” is a smartcard specification that GnuPG supports directly. A card has three key slots: Signature, Encryption and Authentication. The same specification is built into USB tokens:
- YubiKey 5 series. Yubico’s technical manual says the OpenPGP application follows version 3.4 of the specification on firmware 5.2.3 and later (version 2.0 before that). It supports RSA 2048, 3072 and 4096, and from firmware 5.2.3 elliptic curves including Curve25519 (ed25519 for signing and authentication, x25519 for decryption). RSA 1024 was removed in firmware 5.3.2.
- Nitrokey. Nitrokey’s documentation lists the Nitrokey 3, Pro 2, Storage 2 and Start as OpenPGP-card devices.
- Plain smartcards in a USB card reader work the same way.
Every card has two PINs. The user PIN (default 123456) unlocks signing and decryption. The Admin PIN (default 12345678) is needed to change settings and load keys. Both YubiKey and Nitrokey documentation give these defaults. Nitrokey’s documentation says a PIN is blocked after three wrong attempts. An optional Reset Code can unblock the user PIN without the Admin PIN.
Before you start
- GnuPG 2.2 or later. On Debian 13 the card support is a separate package:
sudo apt install scdaemon. Without it,gpg --card-statussays “No SmartCard daemon”. - For YubiKey settings such as touch policy, Yubico’s
ykmantool (packageyubikey-manageron Debian and Ubuntu). - A key with separate subkeys. If you made your key with GnuPG’s defaults you have a primary key [SC] and an encryption subkey [E]. Add a signing and an authentication subkey:
gpg --quick-add-key FPR ed25519 sign 2y gpg --quick-add-key FPR ed25519 auth 2y gpg -K FPR - A backup of the whole secret key, made now, before anything goes to the card (backup guide). The GnuPG manual is blunt: after
keytocard“it is not possible to get that key back from the card - if the card gets broken your secret key will be lost unless you have a backup somewhere.”
Check the card and change the PINs
gpg --card-status
This prints the card’s serial number, Key attributes, PIN retry counter (remaining tries for the user PIN, Reset Code and Admin PIN) and which slots hold keys. Change both PINs straight away:
gpg --card-edit
gpg/card> admin
Admin commands are allowed
gpg/card> passwd
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Choose 3 first (Admin PIN), then 1 (user PIN). Yubico’s ykman documentation gives a minimum of 6 characters for the user PIN and 8 for the Admin PIN. Write the Admin PIN down and keep it with your key backup.
Set the key type on the card
Many cards are set to RSA 2048 by default. If your subkeys are ed25519/cv25519, change the slot type first, still in admin mode:
gpg/card> key-attr
GnuPG asks for each slot (“Changing card key attribute for: Signature key”), offers (1) RSA and (2) ECC, and for ECC lets you choose “Curve 25519”. Use the same type as the subkey you will load. Then type quit.
Move the subkeys to the card
gpg --edit-key FPR
gpg> key 1
gpg> keytocard
Please select where to store the key:
(2) Encryption key
Your selection? 2
gpg> key 1
gpg> key 2
gpg> keytocard
(1) Signature key
Your selection? 1
gpg> key 2
gpg> key 3
gpg> keytocard
(3) Authentication key
Your selection? 3
gpg> save
key N toggles the selection of subkey number N in the order they are listed; a * marks the selected one. Select exactly one subkey before each keytocard. If no subkey is selected, GnuPG offers to move the primary key and asks “Really move the primary key? (y/N)”; answer no for this setup. GnuPG asks for your key passphrase and the Admin PIN. Nothing changes on disk until you type save: then the local secret subkeys are replaced by stubs that point to the card.
Check that it worked
gpg -K FPR
In the listing, ssb> means the subkey is on a smartcard, and a Card serial no. line shows which card. sec# means the primary secret key is not available on this machine. To keep the primary key only in your offline backup, first confirm the backup restores, then remove the primary key’s file from this computer. gpg -K --with-keygrip FPR prints a Keygrip under each key; GnuPG stores each secret key as ~/.gnupg/private-keys-v1.d/KEYGRIP.key. Delete only the file whose keygrip belongs to the sec line, and gpg -K then shows sec#. Whenever you need the primary key (to extend the expiry, add subkeys or certify other keys), restore the backup on an offline machine or temporarily. If unsure, leave the primary key on disk with a strong passphrase; the card already protects the daily-use subkeys.
Test it: echo test | gpg --armor --sign should ask for the card PIN, not for your passphrase.
Generate keys on the card instead
You can also let the card create the keys (gpg --card-edit, admin, generate). The secret keys then never exist outside the card, but you also cannot back them up. GnuPG asks “Make off-card backup of encryption key? (Y/n)”; the GnuPG Card HOWTO recommends yes, because without it everything encrypted to the card is lost if the card breaks. Signing and authentication keys made on the card cannot be backed up at all; if the card is lost you revoke them and make new ones.
YubiKey extras: touch policy
A YubiKey can require you to touch its contact for every operation, so malware cannot quietly use the key while the token is plugged in:
ykman openpgp info
ykman openpgp keys set-touch sig on
ykman openpgp keys set-touch enc on
ykman openpgp keys set-touch aut on
The policies are on, off (the default), fixed (cannot be turned off without deleting the key), cached (touch once, valid 15 seconds) and cached-fixed. ykman openpgp reset wipes all OpenPGP data and sets the PINs back to their defaults.
Use the card for SSH
gpg-agent can act as your SSH agent and use the authentication subkey on the card.
- Turn on SSH support:
echo enable-ssh-support >> ~/.gnupg/gpg-agent.conf gpgconf --kill gpg-agent - Point SSH at gpg-agent. The gpg-agent manual gives this snippet for
~/.bashrc:export GPG_TTY=$(tty) unset SSH_AGENT_PID if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)" fi - Get your SSH public key and add it to
~/.ssh/authorized_keyson the servers:
The output is one line such asgpg --export-ssh-key FPRssh-ed25519 AAAAC3Nz… openpgp:0xBD33A6A9. It comes from the latest valid subkey with authentication capability. - Test with
ssh-add -L(it should list that key) and log in. Keys on an OpenPGP card are offered automatically; you do not need to list them insshcontrol.
If the PIN prompt appears on the wrong terminal or not at all, run gpg-connect-agent updatestartuptty /bye. On Windows, the option for the built-in OpenSSH is enable-win32-openssh-support, and for PuTTY enable-putty-support.
When things go wrong
- “No SmartCard daemon” or “OpenPGP card not available”
- Install
scdaemon, re-plug the token, and rungpgconf --kill all. Some cards show another application first; ingpg --card-edittheopenpgpcommand switches to the OpenPGP application. - User PIN blocked
- Use
passwd→2 - unblock PINwith the Admin PIN, or theunblockcommand with a Reset Code. - Admin PIN blocked or card lost
- You cannot recover keys from the card. Reset the card (for example
ykman openpgp reset, orfactory-resetin admin mode), restore your subkeys from the backup and load them again, or revoke the subkeys and create new ones. - “Secret key not available” on a second computer
- The second computer needs the public key and the stubs. Import your public key there and run
gpg --card-statuswith the card inserted; GnuPG links the card keys to it. Thefetchcommand in--card-editdownloads the public key from the URL stored on the card (set it withurl).
Sources
- gpg(1) manual page, Debian 13 (GnuPG 2.4.7)
- OpenPGP Key Management, GnuPG manual
- Agent Options, GnuPG manual
- GnuPG Smartcard HOWTO: Initialising the card
- OpenPGP Specifics, YubiKey Technical Manual
- OpenPGP Commands, YubiKey Manager (ykman) documentation
- PGP, Yubico Developers
- Importing keys, Yubico Developers
- OpenPGP Card, Nitrokey Documentation
- Change PINs, Nitrokey Documentation