When you use keytocard to import GPG secret subkeys into a YubiKey, the secret key material in that GnuPG environment is replaced with references to the card.
To keep the secret subkeys on your PC, copy them into a temporary GNUPGHOME and run keytocard there.
The Resulting Key Setup
Before starting, the PC holds the public primary key and three secret subkeys for signing, authentication, and encryption. The secret primary key is stored only in an offline backup.
Afterward, the PC retains its secret subkeys, and the YubiKey holds the same subkeys.
Offline backup
└─ Secret primary key
PC
├─ Secret signing subkey
├─ Secret authentication subkey
└─ Secret encryption subkey
YubiKey OpenPGP
├─ Signature slot Secret signing subkey
├─ Authentication slot Secret authentication subkey
└─ Encryption slot Secret encryption subkey
This setup lets you start using a YubiKey without losing the secret subkeys on your PC.
What keytocard Changes
The official GnuPG manual describes keytocard as a command that transfers the selected secret key to a smart card.
After a successful transfer and save, the secret key material in the active GnuPG environment is replaced with a card reference stub.
This stub stores information such as the card’s serial number and requests the corresponding card when the secret key is needed.
Running keytocard in your usual ~/.gnupg therefore replaces the secret subkey material in that environment with stubs.
Running it in a temporary GNUPGHOME replaces only the temporary environment’s secret subkeys, leaving those in your usual environment intact.
Since GnuPG 2.1, gpg-agent has managed secret keys and stubs under private-keys-v1.d.
The description that secret key material resides only in the traditional secret keyring does not apply to current GnuPG 2.x versions.
Tested Environment
This article assumes the following environment.
OS: Ubuntu 24.04.4 LTS
GnuPG: 2.4.4
YubiKey: YubiKey 5C NFC
YubiKey firmware: 5.7.4
OpenPGP application: 3.4
Signing subkey: Ed25519
Authentication subkey: Ed25519
Encryption subkey: Curve25519
The algorithms supported by the YubiKey 5 OpenPGP application vary by firmware and product family. According to Yubico’s documentation, elliptic-curve cryptography, including Ed25519 and X25519, is supported from firmware 5.2.3 onward.
A YubiKey-related keytocard bug in GnuPG 2.4.0 was fixed in 2.4.1.
If you use another version, check its release notes as well.
Check the Keys and Card First
First, check the GnuPG version and your current secret keys.
gpg --version
gpg --list-secret-keys \
--keyid-format LONG \
--with-subkey-fingerprint
Identify the target key by the public primary key’s full fingerprint rather than a short key ID. Set the following variable to that fingerprint, with spaces removed.
PRIMARY_FINGERPRINT="FULL_FINGERPRINT_OF_YOUR_PUBLIC_PRIMARY_KEY"
The markers at the start of entries in the secret key listing also have specific meanings.
sec,ssb: usable secret key material is availablesec#,ssb#: the corresponding secret key material is unavailablesec>,ssb>: the secret key is on a smart card
Before proceeding, confirm that the secret primary key appears as sec# and all three secret subkeys appear as ssb.
Connect the YubiKey and check its status as well.
gpg --card-status
Check the following items.
- The card is recognized as an OpenPGP application.
Key attributesmatch the algorithms of the keys you will import.- The fingerprints shown for
Signature key,Encryption key, andAuthentication key. - You have changed both the User PIN and Admin PIN from their defaults.
Compare the card and PC fingerprints for each purpose, then choose the appropriate next step.
- All three slots are empty: create a temporary environment and proceed with the import.
- All three slots match the PC’s subkeys: the desired setup is already complete, so no further import is needed.
- A slot contains a different key, or only some slots match: check the card’s purpose and your backups before overwriting anything.
If you overwrite a slot containing an existing key, you cannot recover that secret key from the YubiKey.
Seeing the same fingerprint already listed is not a reason to repeat keytocard.
A backup of the secret primary key does not necessarily include the current secret subkeys. A YubiKey cannot serve as a backup of secret keys, so first verify that you also have an offline backup from which you can restore each S, A, and E secret subkey.
Create a Temporary GnuPG Environment
Create a temporary directory with mktemp and restrict access to its owner.
umask 077
TEMP_GNUPGHOME="$(mktemp -d)"
chmod 700 "$TEMP_GNUPGHOME"
printf '%s\n' "$TEMP_GNUPGHOME"
Leave the GNUPGHOME environment variable unchanged and pass --homedir "$TEMP_GNUPGHOME" to each command to avoid confusing the temporary and usual environments.
Copy the Secret Subkeys into the Temporary Environment
Export the secret subkeys from your usual environment and pipe them directly into GnuPG in the temporary environment.
gpg --export-secret-subkeys "$PRIMARY_FINGERPRINT" |
gpg --homedir "$TEMP_GNUPGHOME" --import
--export-secret-subkeys does not mean “export only the specified subkey on its own.”
It outputs a key block that includes the public primary key, replacing only the secret primary key portion with an unusable dummy.
The output contains the secret subkey material, so saving it somewhere unsafe would expose the secret subkeys.
Piping the export directly into the import avoids creating an intermediate file containing secret keys. The public portion is included, so there is no need to import the public key separately.
Check the result after importing.
gpg --homedir "$TEMP_GNUPGHOME" \
--list-secret-keys \
--keyid-format LONG \
--with-subkey-fingerprint
Confirm that the secret primary key appears as sec# and the signing, authentication, and encryption subkeys appear as ssb.
Do not proceed to keytocard if an unexpected key appears or any required subkey has a # or > marker.
Match the YubiKey’s Key Attributes
Each YubiKey slot has a key attribute specifying the algorithm of the key it holds.
Skip this section if gpg --card-status already shows the following.
Key attributes ...: ed25519 cv25519 ed25519
Edit the card only if the slots are empty and the key attributes differ.
gpg --homedir "$TEMP_GNUPGHOME" --edit-card
Enable administrative commands and run key-attr.
gpg/card> admin
gpg/card> key-attr
You will be prompted to configure Signature, Encryption, and Authentication, in that order. For all three, choose ECC as the key type and Curve 25519 as the curve.
Signature key: ed25519
Encryption key: cv25519
Authentication key: ed25519
Exit the card editor after completing the settings.
gpg/card> quit
Then display the card status.
gpg --homedir "$TEMP_GNUPGHOME" --card-status
Confirm that Key attributes now reads ed25519 cv25519 ed25519.
Changing key attributes also writes to the YubiKey itself, so perform this operation only when the slots are empty.
Import the Secret Subkeys into the YubiKey
Edit the key in the temporary environment.
gpg --homedir "$TEMP_GNUPGHOME" \
--edit-key "$PRIMARY_FINGERPRINT"
keytocard operates on the subkey selected with the key command.
Subkey numbers vary between keys, so compare the editor’s usage and fingerprints with the following table.
| usage | Algorithm | Destination |
|---|---|---|
| S | Ed25519 | Signature key |
| A | Ed25519 | Authentication key |
| E | Curve25519 | Encryption key |
Select exactly one subkey and use keytocard to import it into the corresponding slot.
The selected subkey is marked with *.
gpg> key <target subkey number>
gpg> keytocard
After importing, use the same key command to deselect it, then repeat for the remaining subkeys.
gpg> key <target subkey number>
Once all three subkeys have been imported, save the changes.
gpg> save
Running save replaces each secret subkey’s material in the temporary environment with a card reference stub.
These edits are not saved to the secret subkeys in your usual environment.
Check the Card and Your Usual Environment
First, inspect the YubiKey’s slots from the temporary environment.
gpg --homedir "$TEMP_GNUPGHOME" --card-status
gpg --homedir "$TEMP_GNUPGHOME" \
--list-secret-keys \
--keyid-format LONG \
--with-subkey-fingerprint
Confirm that Signature key, Authentication key, and Encryption key show the fingerprints of the corresponding target subkeys.
In the temporary environment’s secret key listing, subkeys transferred to the card appear as ssb>.
Next, check your usual environment without --homedir.
gpg --list-secret-keys \
--keyid-format LONG \
--with-subkey-fingerprint
Confirm that each S, A, and E subkey still appears as ssb in your usual environment and has not changed to ssb>.
Test Signing and Decryption with the YubiKey
--card-status alone does not confirm that the secret keys can be used, so create a signature in the temporary environment.
printf 'YubiKey signing test\n' > "$TEMP_GNUPGHOME/test.txt"
gpg --homedir "$TEMP_GNUPGHOME" \
--armor \
--detach-sign "$TEMP_GNUPGHOME/test.txt"
gpg --homedir "$TEMP_GNUPGHOME" \
--verify "$TEMP_GNUPGHOME/test.txt.asc" \
"$TEMP_GNUPGHOME/test.txt"
Next, encrypt data with your public key and decrypt it using the YubiKey.
gpg --homedir "$TEMP_GNUPGHOME" \
--armor \
--recipient "$PRIMARY_FINGERPRINT" \
--output "$TEMP_GNUPGHOME/test.txt.asc.gpg" \
--encrypt "$TEMP_GNUPGHOME/test.txt"
gpg --homedir "$TEMP_GNUPGHOME" \
--decrypt "$TEMP_GNUPGHOME/test.txt.asc.gpg"
Test the authentication subkey against an actual authentication target, such as SSH.
Configuring gpg-agent for SSH is outside the scope of this article.
Remove the Temporary Environment
After confirming that the card’s keys work and the secret subkeys remain in your usual environment, stop the temporary environment’s gpg-agent.
gpgconf --homedir "$TEMP_GNUPGHOME" --kill all
Confirm that the deletion target is the path created by mktemp, then remove the temporary environment.
case "$TEMP_GNUPGHOME" in
/tmp/tmp.*) rm -rf -- "$TEMP_GNUPGHOME" ;;
*) printf 'Unexpected path: %s\n' "$TEMP_GNUPGHOME" >&2 ;;
esac
unset TEMP_GNUPGHOME
unset PRIMARY_FINGERPRINT
This deletion does not guarantee physical erasure of data left on an SSD or other storage device. If your threat model includes recovery after deletion, work in an encrypted temporary filesystem or a disposable environment isolated from the network.
What Keeping Two Copies of the Same Secret Subkeys Means
Secret keys imported into a YubiKey cannot be exported from the card again as ordinary secret key files. A YubiKey therefore provides a place to use secret keys, but it is not a backup.
In this setup, the PC also retains the same secret subkeys. If an attacker compromises the PC and obtains those subkeys, they can sign, authenticate, and decrypt with them without possessing the YubiKey. Importing the keys into a YubiKey does not provide hardware protection for the secret subkeys on the PC.
The purpose of this setup is to try using a YubiKey without losing the secret subkeys on your PC. After verifying that everything works and checking your backups, the next step is to decide whether to keep only stubs on the PC or create dedicated YubiKey subkeys in an offline environment.