This utility helps those who carry multiple yubikeys with the same subkeys.
It removes the smartcard specific keygrip files stored in the.gnupg/private-keys-v1.d
directory , and updates the directory with the keygrip files generated by the new yubikey.
The program is triggered currently by a set of udev rules that are specific for Yubikeys.
- Run
make configure
Right now, this justsed
's the current user's $USER variable to theinser-yubi.sh
script. - Run
sudo make install
This copies the udev rule to/etc/udev/rules.d/
and copies the script ,executed upon matching of the udev rules,insert-yubi.sh
to/usr/local/bin
It is nice to have the same subkeys on multiple smartcards (e.g., the Yubikey) and to not get the error message: Please insert the card with serial number:
when inserting a different smartcard with the same subkeys.
gpg (GnuPG) 2.2.4
and libgcrypt 1.8.1
do not update the <keygrip>.key
files (aka 'stubs'), in <GPG_HOME>/private-keys-v1.d
when a new yubikey is inserted that produces the same keygrip (unique hash). However, information specific to the smart card is also embedded in the keygrip file which is read and used by smartcard readersvalidation issues further by downstream services.
For GPG Keys, I use a model basically outlined in this guide I have a set up of three yubikeys and one encrypted and highly protected backup. One yubikey has the master secret key and two have the gpg subkeys for day-to-day use. This has given me a much more seamless experience as I migrate to what I hope to be a more secure setup for interfacing with the interwebs.
A little more info on what gpg is doing under the hood
- Shadowed Private Key Format
The GPG GnuPG doc keyformat.txt has a section on shadowed private key format, which is how the gpg service(s) "keep track of keys stored on IC cards."
Looking at the last 64 bytes using tail
:
~/.gnupg/private-keys-v1.d$ tail -c 64 *card1 *card2
==> 02236F4578D3652E28618D804C13A951A69A1BDE.key.card1 <==
)(1:e3:)(8:shadowed5:t1-v1(16:$ $9:OPENPGP.2))))
==> 02236F4578D3652E28618D804C13A951A69A1BDE.key.card2 <==
)(1:e3:)(8:shadowed5:t1-v1(16:bRT9:OPENPGP.2))))
Looking at the diff using diffoscope
provides much richer insight.
00000220: 9afa d9fa ec9f 8d29 2831 3a65 333a 0100 .......)(1:e3:..
00000230: 0129 2838 3a73 6861 646f 7765 6435 3a74 .)(8:shadowed5:t
00000240: 312d 7631 2831 363a d276 0001 2401 0201 1-v1(16:.v..$...
-00000250: 0006 0904 2498 0000 393a 4f50 454e 5047 ....$...9:OPENPG
+00000250: 0006 0862 5254 0000 393a 4f50 454e 5047 ...bRT..9:OPENPG
00000260: 502e 3229 2929 29 P.2))))