BXG Blog

Improving Private Key Security with a Yubikey: Using the key for GPG

In the previous steps, you should have ended up with one or more Yubikeys each containing a unique authentication key and shared encryption and signing keys. However, since all the setup was done with GNUPGHOME set to an alternate location, your normal gnupg keyring doesn’t know anything about the new keys or cards. We’ll need to import the public key back into gnupg before it can be used for anything.

If you set the URL to wherever you uploaded your final public key in the previous step, you can now use that to re-associate the keys stored on your card with your regular gnupg keyring. Make sure you don’t have a custom GNUPGHOME set, insert the card into the computer you plan to use it with, and then edit the card:

$ gpg2 --edit-card

gpg/card> fetch
gpg: requesting key from 'https://www.bxg.org/pgpkey.txt'
gpg: key 24770C40DF746792: "Benjamin Gordon <ben@bxg.org>" 2 new signatures
gpg: key 24770C40DF746792: "Benjamin Gordon <ben@bxg.org>" 2 new subkeys
gpg: Total number processed: 1
gpg:            new subkeys: 2
gpg:         new signatures: 2

gpg/card> list

Reader ...........: 1050:0407:X:0
Application ID ...: D2760001240102010006070201920000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 07020192
Name of cardholder: Benjamin Gordon
Language prefs ...: en
Sex ..............: male
URL of public key : https://www.bxg.org/pgpkey.txt
Login data .......: ben
Signature PIN ....: forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 2
Signature key ....: C9BB 2749 B901 6A9F 55BD  A603 9353 64AE 6E80 71BD
      created ....: 2017-12-04 02:30:03
Encryption key....: 749F AF05 0AAA 6199 CF87  198E 1F9F 9EEF A71F F33A
      created ....: 2017-12-04 02:28:44
Authentication key: 5C41 B63E CC5C F91F 84FD  537E 23FB AF24 3D1C ED5A
      created ....: 2018-10-30 04:23:47
General key info..: sub  rsa2048/935364AE6E8071BD 2017-12-04 Benjamin Gordon <ben@bxg.org>
sec#  rsa3072/24770C40DF746792  created: 2017-12-04  expires: 2027-12-02
ssb#  rsa2048/BAB118CABB39E1EB  created: 2017-12-04  expires: 2019-12-04
ssb#  rsa2048/D68B8C2FE5C5D22E  created: 2017-12-04  expires: 2019-12-04
ssb>  rsa2048/81676743C733D672  created: 2018-10-30  expires: 2020-10-29
                                card-no: 0006 07020132
ssb>  rsa2048/23FBAF243D1CED5A  created: 2018-10-30  expires: 2020-10-29
                                card-no: 0006 07020192
ssb>  rsa2048/1F9F9EEFA71FF33A  created: 2017-12-04  expires: 2019-12-04
                                card-no: 0006 07020192
ssb>  rsa2048/935364AE6E8071BD  created: 2017-12-04  expires: 2019-12-04
                                card-no: 0006 07020192
ssb#  rsa2048/9F7CA19A0F5E9800  created: 2017-12-04  expires: 2019-12-04

The ssb# lines show keys that are on other cards, and the ssb> lines indicate keys that are now associated with the current card. If you need to change which card is associated with a key, you can do something like this:

$ gpg2 --with-keygrip -K 24770C40DF746792
sec#  rsa3072/24770C40DF746792 2017-12-04 [C] [expires: 2027-12-02]
      BCD38E83FED87BA945B65D7B24770C40DF746792
      Keygrip = 382DC50906174C26C58C29EA3045A1F4705B4929
uid                 [ultimate] Benjamin Gordon <ben@bxg.org>
ssb#  rsa2048/BAB118CABB39E1EB 2017-12-04 [A] [expires: 2019-12-04]
      Keygrip = 3E924608C85F40421CDA6B9DC7279667C66D0FA3
ssb#  rsa2048/D68B8C2FE5C5D22E 2017-12-04 [A] [expires: 2019-12-04]
      Keygrip = 98A55CDE2120F15D7E4CBC635E6BCEEF74BBA759
ssb>  rsa2048/81676743C733D672 2018-10-30 [A] [expires: 2020-10-29]
      Keygrip = 8A11703479077BB1CCD2B1CD9A9292DC7A463B29
ssb>  rsa2048/23FBAF243D1CED5A 2018-10-30 [A] [expires: 2020-10-29]
      Keygrip = AA6A267981AFC1F1FD865B32EC802BF05DCB5A75
ssb>  rsa2048/1F9F9EEFA71FF33A 2017-12-04 [E] [expires: 2019-12-04]
      Keygrip = A1FE7AFB10DED4B2DC02A747D34499F71CA4792E
ssb>  rsa2048/935364AE6E8071BD 2017-12-04 [S] [expires: 2019-12-04]
      Keygrip = 04E1A55269437F6CB94A96CDEFFF6A904B5F4F60
ssb#  rsa2048/9F7CA19A0F5E9800 2017-12-04 [A] [expires: 2019-12-04]
      Keygrip = AEDDCB7AC50EC2BF5567AA5D1021DA17349E2D69

The keygrip for each subkey will correspond to a file under ~/.gnupg/private-keys-v1.d. Delete these files and run gpg2 --card-status to get them re-associated with the new card.

Now gpg has your key and knows to look on your card for the secret parts. Edit ~/.gnupg/gpg.conf and set the default-key to your signing subkey.

Now we can actually use the keys (finally):

$ echo test | gpg2 -ear 0x24770C40DF746792 --sign | gpg2 -d
gpg: using "935364AE6E8071BD" as default secret key for signing
gpg: encrypted with 2048-bit RSA key, ID 1F9F9EEFA71FF33A, created 2017-12-04
      "Benjamin Gordon <ben@bxg.org>"
test
gpg: Signature made Tue 30 Oct 2018 10:45:55 PM MDT
gpg:                using RSA key C9BB2749B9016A9F55BDA603935364AE6E8071BD
gpg: Good signature from "Benjamin Gordon <ben@bxg.org>" [ultimate]

You should be prompted for your PIN if you haven’t typed it recently. If you set up the touch requirements in the previous step, your Yubikey will silently blink until you touch it before signing or decrypting.

Next up: Replacing ssh-agent with gpg-agent.