My GPG setup consists of two Yubikey keys, each holding same set of keys in its internal storage. Reason behind this is that keys can’t be exported from the Yubikey (at least you shouldn’t be able to do that). There’s also the PIN protecting the usage of those keys. There are also additional security mechanisms making this setup quite more secure than keeping GPG key directly on the machine, but that’s beyond the scope of this article.

Aside of having off-site backups of the keys, I also have 2 Yubikeys, so that if something happens to one (gets broken or something like that) I’m not inconvenienced much and can wait for new Yubikey order to get delivered :-). Due to this fact, I sometimes use them interchangeably on my machines.

Issue with this approach is that GPG remembers serial number of the Yubikey (smart card) on which private key resides, and won’t automatically try any card plugged into the computer. So let’s say that you encrypt some super secret file:

echo test > test.txt
gpg -e -s -a -r ivan@tomica.net test.txt

You get the result:

$ cat test.txt.asc
-----BEGIN PGP MESSAGE-----

hQIMA+AtI2yXVOKbAQ/7Bh1cC6RgMx9T4FFeFg6fE/mg2y8GLPbr0nWCRIuA+OY6
ttpzb/h32zOiglHmHFWYtoDaq3MonzritisQD2mvHtWYvt2Q/Qk3rDRlFs8wExGk
DAQRC4NXeNV8ADosViHynAtAhfLIET/MddBFu5rHRAAoTASaeN1MrndNeerpjVYY
drz8n87aPY1qJXIMKv7JSBrhPW4B6YCT/tfaJaI17cF9QAuiXuBDT5/pYzoOwZ1w
J861KOGzNLApXhlBaBe+4ABiHJcqr/IFGPDWGvJBWhSEd7lOVFE6vufDs7MM4Mv3
6Vx3Jjac/5F1wwDfvKfFKSDXiY3APi2oHzxx8RXVg1XrikOCWXFSIPRiD/gm15hB
/ZIR3zQWLnbF5/UMi4fFJoBRlwNQAPQtfFiEu3dAOZkJ+jALbMV4oi0vofWo/RnT
/hA4u1ArLSsCYb1A41Bd0lmJx5qKFafqqWeSefe0uOR0deFGsI3+A0UkMu3nGBgC
9X7nRiqmwn5SUZCnGqbGaePmkB7ZKObr14YjMYMBQr/ojCvvKfii5u0PpBh5kU2T
T+6JZ4YDIcPlXuluvA4MxExT1iLWMPSgp8MWoe2YULv1yOUsm9axitHrZP93/fll
HjQotibaZpuTF530Hxc/cHPwxt6a8K5h1onqOtM4ksSbtdI02ax9BG0jc7Mz6nTS
6QFyepi01AOn79aJJStUNHalFDaiEKjHYTuW0QTV2rRXQ5U3qbH0c9JNjK3hnsgU
rFaPYuXZbyYhRPM1eKmcSX245BKwzayV0RwYCC9AL4Sz675tw4bOio79ZCXX8Hok
ETpFsFOB79B1FY0G+uV1Ko6WvIsy1sFg5AUeCTgsXnYurrlyrL02ZPvl580/WaJ9
o45hIL1JOzluDy+Fk18x55W3ZQc9lExqyyXcSow39yJqpt4fvl0q6JBp0N/jVZZ+
ZSv2j58Tb+nD2NtdNAJPrZiNGA2wnmo3XAooO1Ox5qkREZjQ1lxOO0dFbgNWIicy
szrxdV34ics1MTsAS0NTXxKgrDarc6zYUUf7Q77AuJQrOps5k33iLSywC/kws4Xb
MJaTyzmxuIzJriRHarppz/aC0+zfA3AJDX2CwufDmr67fqmv6olGZJsvTds3tal8
DgRa+k1RjRVHfKc1oyFF0CBV/2GP3xbKT1vZOl5dAaA7S86T1NM+HdDxOusYEH23
dRMJ5paXGlEg4rOsYyqSn1GqD0xXsIAHY1qu3gzQkyhiFEtHCv/etUOiGQ2EWVH6
n41rDifJH3ZMgFw5L9GaaRoL2F1p5F39OtODyqIRHNVzyz/8S34xQM35nioJNiEb
zVfxhTvx46GI4Ui/lCXOXJxrBQGKnbVxH21I8zaStUC8kJck2jvOHB0ZaL4+9T4X
ba08b7WV1rl1dlWE+Q6OlCoJo1Ic5Ea+Xllvwnrsbynz78mCDrTi1r5PNttVGKE8
zhE6tKEEB5PosLP4qB5yP1PShuIoDUokLn3cQrEinujMkjaXlP9rg/TmuAeSIvxH
YaXIrx0GbO5WEFwmH3R3hrzuhpUNaRkMtOgpJj2FsXXzYg==
=VvyL
-----END PGP MESSAGE-----

Trying to decrypt it, all works as it should:

$ gpg -d test.txt.asc
...
test
...

But when I remove the key, and insert the other one holding the same GPG key, I get asked to re-insert the old one:

Failing to do so, will result in GPG not being able to decrypt the file:

[ivan@tomica-main ~]$ gpg -d test.txt.asc
gpg: encrypted with 4096-bit RSA key, ID E02D236C9754E29B, created 2021-07-06
      "Ivan Tomica <ivan@tomica.net>"
gpg: public key decryption failed: Operation cancelled
gpg: decryption failed: No secret key

This is due to the fact that each key is mapped to some smart card serial number as per keyinfo output:

$ gpg-connect-agent 'keyinfo --list' /bye
S KEYINFO 197F6A456939C682671363C2C848329D311098EF T D2760001240103040006106207850000 OPENPGP.3 - - - - -
S KEYINFO 7B5406ED88BDA94A15206510268BE06D5756640F T D2760001240103040006106207850000 OPENPGP.2 - - - - -
S KEYINFO AA31DF93761CADDB034106808B6529665AFDC6F5 T D2760001240103040006106207850000 OPENPGP.1 - - - - -
OK

Luckily, this can easily be changed to point to the new yubikey by simply asking gpg-agent to learn the new serial:

$ gpg-connect-agent "scd serialno" "learn --force" /bye
S SERIALNO D2760001240103040006106207690000
OK
S PROGRESS learncard k 0 0
S PROGRESS learncard k 0 0
S PROGRESS learncard k 0 0
OK

$ gpg-connect-agent 'keyinfo --list' /bye
S KEYINFO 197F6A456939C682671363C2C848329D311098EF T D2760001240103040006106207690000 OPENPGP.3 - - - - -
S KEYINFO 7B5406ED88BDA94A15206510268BE06D5756640F T D2760001240103040006106207690000 OPENPGP.2 - - - - -
S KEYINFO AA31DF93761CADDB034106808B6529665AFDC6F5 T D2760001240103040006106207690000 OPENPGP.1 - - - - -
OK

So attemptying to decrypt the file with that key again, I get prompted to input the PIN for that second Yubikey:

And naturally, decryption works:

$ gpg -d test.txt.asc
...
test
...