Load Keys into YubiKey

This page covers setting up the YubiKey and loading your PGP keys into it.

Initial Setup

These are things you should do when you start using a new YubiKey.

Reset the OpenPGP app

If you want to "erase" everything about OpenPGP from the YubiKey and "start fresh", you can reset the OpenPGP app. Doing this will erase any keys stored in the YubiKey, and reset the PINs back to their factory-original state (which are explained below.)

Note that this is the only way to recover if you have entered the wrong Admin PIN too many times and totally locked up the OpenPGP app.

Yubico's documentation explains how to reset the OpenPGP app. Rather than trying to copy it, I'll just point you there.

Resetting the OpenPGP Application on the YubiKey

Set PINs

If you have not already done so, you should set your own PIN and Admin PIN codes.

  • The PIN code is what you will use on a regular basis, to do things like generate signatures, decrypt messages, or perform SSH authentication. If somebody enters the wrong PIN code too many times, the OpenPGP app will lock itself, and you will need to use the Admin PIN code (or PUK code, if you set one) to "unlock" the PIN.

    ℹ️ For a new (or newly reset) YubiKey, this is 123456.

  • The Admin PIN code is used to load PGP keys into the YubiKey, or to change the YubiKey's OpenPGP settings. It can also be used to unlock the PIN code after the wrong PIN was entered too many times.

    Note that it cannot be used to perform the day-to-day operations that you would normally use the PIN code for, and it cannot be used to "force-set" the PIN code. If you don't know the PIN code,

    ℹ️ For a new (or newly reset) YubiKey, this is 12345678.

  • There is a third code, known as an "Reset Code". (You may also see the term "PUK code", which is the term used with the SIM cards used with GSM phones.)

    If this code is set, it can be used to "unlock" the PIN code after too many invalid attempts, without allowing access to change settings or load new keys.

    ℹ️ For a new (or newly reset) YubiKey, this code is not set.

ℹ️ These PINs only apply to the OpenPGP app.

If you use the same YubiKey for FIDO2, U2F, or PIV/CCID, and those systems require you to set up a PIN, they each have their own PINs which are totally separate from the PINs you use for OpenPGP.

Set Admin PIN

$ gpg --change-pin
gpg: OpenPGP card no. D27600012401xxxxxxxxxxxxxxxxxxxx detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 3

At this point your workstation will ask for the following, usually as separate prompts:

  • The current Admin PIN (it will probably just say "the Admin PIN").
  • The new Admin PIN.
  • The new Admin PIN again, to verify that you typed it correctly.
PIN changed.

Set PIN

Next, set the PIN you'll use on a regular basis in order to generate signatures, decrypt messages, or perform SSH authentication.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 1
  • Enter the current PIN.
  • Enter the new PIN.
  • Enter the new PIN again.

Note that if the current PIN was wrong, this command will fail, you will receive a "Error changing the PIN: Bad PIN" error, and the PIN failure counter will be updated. If you enter the wrong PIN too many times (usually 3, although this can be changed), the PIN will be "locked" and cannot be used without resetting it.

PIN changed.

Set a Reset Code

Once the PIN is set, you may want to set a Reset Code, but it isn't any less secure if you don't.

Personally I don't have one, but if I were managing YubiKeys for a company and might need to help a user who locked their YubiKey by entering the wrong PIN too many times, and they weren't able to physically bring the YubiKey to me, I would definitely want to be able to give them a code which unlocks their PIN without giving them full access to change everything on the card.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 4
  • Enter the Admin PIN (which you just set above).
  • Enter the new Reset Code.
  • Enter the new Reset Code again.
PIN changed.

ℹ️ Using the Reset Code

If you ever lock your normal PIN and need to use the Reset Code to reset it, do the following:

  • gpg --card-edit
  • admin (to enable admin-level commands)
  • unblock

For the record, I've only ever done this once, while writing this documentation, to make sure it worked as advertised. It accepted the PUK and allowed me to set a new PIN, which also reset the "bad PIN" counter back to zero.

Finished

When you're finished setting the PIN codes, use "q" to finish.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? q

Personalize the Card

This section will involve storing information on the YubiKey which identifies you as the owner of the key.

$ gpg --card-edit

Enter some basic info about the "owner" of the card, along with their preferred language. This information is stored on the YubiKey, and will be visible to anybody who runs "gpg --card-info" or "gpg --card-edit" while the YubiKey is plugged in.

gpg/card> name
Cardholder's surname: Simpson
Cardholder's given name: John

gpg/card> login
Login data (account name): j..1@j....net

gpg/card> lang
Language preferences: en

You can also enter a URL where the corresponding public key can be downloaded. Doing this allows you to use the "gpg --edit-card" command's "fetch" sub-command to load your public keys into a new computer's keyring. PGPCards only hold secret keys - they don't hold public keys, user IDs, signatures, or expiration dates.

This is not required. If you don't have, or don't want, a copy of your public key saved on a web site somewhere, feel free to skip this step.

gpg/card> url
URL to retrieve public key: https://jms1.pub/jms1.pub.asc

You can also set a flag which tells the YubiKey to require the PIN to be entered, every time a signature is generated. Without this, you will be asked for the PIN the first time you generate one, and the YubiKey will "stay unlocked" and generate more signatures as requested, until it is unplugged from the computer.

gpg/card> forcesig

To see the updated state of the card, just hit RETURN at the "gpg/card>" prompt.

gpg/card>

Reader ...........: Yubico Yubikey 4 OTP U2F CCID
Application ID ...: D27600012401xxxxxxxxxxxxxxxxxxxx
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 06940447
Name of cardholder: John Simpson
Language prefs ...: en
Sex ..............: unspecified
URL of public key : https://jms1.pub/jms1.pub.asc
Login data .......: j..1@j....net
Signature PIN ....: forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

When you're happy with the settings, use "q" to exit the "gpg --card-edit" command.

gpg/card> q

Remove and re-insert the Yubikey.

From this point forward, you will need to enter the PIN in order to make use of any keys, and you will need to enter the Admin PIN in order to load keys or change settings.

Load secret keys

The YubiKey's OpenPGP app has three "slots", each of which can hold the secret half of a PGP key or subkey. The slots are intended for keys with the Signature, Encryption, and Authentication flags. Be sure the keys you load into each slot have the appropriate capability flag (i.e. if a subkey only has the [E] capability, don't load it into a slot other than the Encryption slot).

Which keys need to be sent?

If you only plan to use the YubiKey for SSH, you only need to load an Authentication key on the YubiKey. If you also plan to use the YubiKey for other PGP operations, you should load encryption and signature keys as well.

How do you clear the key from a slot?

I'm only aware of two ways to do this.

  • Load a different key into the same slot, which overwrites whatever key is currently there.

  • Reset the OpenPGP app. This clears all of the slots.

    Of course, you then have to set everything up from scratch again. I've done this several times, once you're used to it the longest part of the process is waiting for Tails to finish booting on that ancient netbook with the world's slowest supposedly USB-3 port... 😒

Open the PGP key

Use "gpg --edit-key" to work with the key.

$ gpg --edit-key 6353320118E1DEA2F38EAE806B2EDC90B5C6DC30
gpg (GnuPG/MacGPG2) 2.2.0; Copyright (C) 2017 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/0x6B2EDC90B5C6DC30
     created: 2017-05-27  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x297E5961AB566594
     created: 2017-05-27  expires: never       usage: E
ssb  rsa4096/0xBA6C2A169C6C0F60
     created: 2017-11-10  expires: never       usage: A
[ultimate] (1). John M. Simpson <j..1@v......com>
[ultimate] (2)  John M. Simpson <j..1@j....net>

gpg>

We will be using the key command below to select or de-select subkeys. This command toggles the selection status of a subkey.

  • Each subkey is "numbered", although the numbers are not shown. Entering "key 1" will toggle the asterisk on the first "ssb" entry, and so forth.

  • It is possible to have multiple subkeys selected at the same time, however only one key or subkey can be selected when sending them to the YubiKey.

  • If no subkeys are selected (as in the example above), the primary key will be considered as selected, even though it will not have an asterisk after the "sec" label.

Be very careful about which key or subkey is selected when sending keys to the YubiKey.

Load the Authentication key

Make sure the Authentication subkey (the one with "usage: A") is the only one selected.

gpg>

sec  rsa4096/0x6B2EDC90B5C6DC30
     created: 2017-05-27  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x297E5961AB566594
     created: 2017-05-27  expires: never       usage: E
ssb  rsa4096/0xBA6C2A169C6C0F60
     created: 2017-11-10  expires: never       usage: A
[ultimate] (1). John M. Simpson <j..1@v......com>
[ultimate] (2)  John M. Simpson <j..1@j....net>

gpg> key 2

sec  rsa4096/0x6B2EDC90B5C6DC30
     created: 2017-05-27  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x297E5961AB566594
     created: 2017-05-27  expires: never       usage: E
ssb* rsa4096/0xBA6C2A169C6C0F60
     created: 2017-11-10  expires: never       usage: A
[ultimate] (1). John M. Simpson <j..1@v......com>
[ultimate] (2)  John M. Simpson <j..1@j....net>

gpg>

As you can see, there is now an asterisk next to the second subkey, which has the "A" capability, and there are no asterisks on any other subkeys.

Send the selected sub-key to the Authentication slot on the Yubikey (or the "card", as gpg calls it.)

gpg> keytocard
Please select where to store the key:
   (3) Authentication key
Your selection? 3

gpg>

Load the encryption key

In this case, we want to send the subkey with the "E" capability, so first turn off the asterisk on the authentication subkey, then turn on the asterisk on the encryption subkey.

gpg>

sec  rsa4096/0x6B2EDC90B5C6DC30
     created: 2017-05-27  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x297E5961AB566594
     created: 2017-05-27  expires: never       usage: E
ssb* rsa4096/0xBA6C2A169C6C0F60
     created: 2017-11-10  expires: never       usage: A
[ultimate] (1). John M. Simpson <j..1@v......com>
[ultimate] (2)  John M. Simpson <j..1@j....net>

gpg> key 2

sec  rsa4096/0x6B2EDC90B5C6DC30
     created: 2017-05-27  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x297E5961AB566594
     created: 2017-05-27  expires: never       usage: E
ssb  rsa4096/0xBA6C2A169C6C0F60
     created: 2017-11-10  expires: never       usage: A
[ultimate] (1). John M. Simpson <j..1@v......com>
[ultimate] (2)  John M. Simpson <j..1@j....net>

gpg > key 1

sec  rsa4096/0x6B2EDC90B5C6DC30
     created: 2017-05-27  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb* rsa4096/0x297E5961AB566594
     created: 2017-05-27  expires: never       usage: E
ssb  rsa4096/0xBA6C2A169C6C0F60
     created: 2017-11-10  expires: never       usage: A
[ultimate] (1). John M. Simpson <j..1@v......com>
[ultimate] (2)  John M. Simpson <j..1@j....net>

gpg>

Next, send the key to the card.

gpg> keytocard
Please select where to store the key:
   (2) Encryption key
Your selection? 2

gpg>

Load the signature key

For this key, you're going to need a key or subkey with the "S" capability.

  • In most cases, the primary key will be the only one with the "S" capability. If so, use the key command to make sure that NO subkeys have an asterisk next to them. (The example below shows this.)

  • If you have a separate signing subkey, make sure that key is selected.

gpg>

sec  rsa4096/0x6B2EDC90B5C6DC30
     created: 2017-05-27  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb* rsa4096/0x297E5961AB566594
     created: 2017-05-27  expires: never       usage: E
ssb  rsa4096/0xBA6C2A169C6C0F60
     created: 2017-11-10  expires: never       usage: A
[ultimate] (1). John M. Simpson <j..1@v......com>
[ultimate] (2)  John M. Simpson <j..1@j....net>

gpg > key 1

sec  rsa4096/0x6B2EDC90B5C6DC30
     created: 2017-05-27  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x297E5961AB566594
     created: 2017-05-27  expires: never       usage: E
ssb  rsa4096/0xBA6C2A169C6C0F60
     created: 2017-11-10  expires: never       usage: A
[ultimate] (1). John M. Simpson <j..1@v......com>
[ultimate] (2)  John M. Simpson <j..1@j....net>

gpg>

Send the key to the YubiKey.

gpg> keytocard
Really move the primary key? (y/N) y
Please select where to store the key:
   (1) Signature key
   (3) Authentication key
Your selection? 1

gpg>

Exit

Technically we're finished, BUT ... we need to be careful.

This next command will quit out of the "gpg --card-edit" command, and it will ask if you want to save changes. IF YOU SAY YES, the secret keys you just installed on the YubiKey will be REMOVED from the secret keyring files on the computer.

Unless you are 100% sure that's what you want to do (i.e. if you have a known-good backup of the secret keys), BE SURE TO SAY NO.

gpg> q
Save changes? (y/N) n
Quit without saving? (y/N) y

Now if you query the card, you will see the keys in the three slots.

$ gpg --card-status

Reader ...........: Yubico Yubikey 4 OTP U2F CCID
Application ID ...: D27600012401xxxxxxxxxxxxxxxxxxxx
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 06940447
Name of cardholder: John Simpson
Language prefs ...: en
Sex ..............: unspecified
URL of public key : https://jms1.net/6B2EDC90B5C6DC30.pub.asc
Login data .......: j..1@j....net
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: 6353 3201 18E1 DEA2 F38E  AE80 6B2E DC90 B5C6 DC30
      created ....: 2017-05-27 22:28:31
Encryption key....: 0660 766F 2768 F41F D4B9  1DB7 297E 5961 AB56 6594
      created ....: 2017-05-27 22:28:31
Authentication key: BBA5 C6BB 23D2 B53B 0D0F  6C0B BA6C 2A16 9C6C 0F60
      created ....: 2017-11-10 23:29:14
General key info..: pub  rsa4096/0x6B2EDC90B5C6DC30 2017-05-27 John M. Simpson <j..1@v......com>
sec   rsa4096/0x6B2EDC90B5C6DC30  created: 2017-05-27  expires: never
ssb   rsa4096/0x297E5961AB566594  created: 2017-05-27  expires: never
ssb   rsa4096/0xBA6C2A169C6C0F60  created: 2017-11-10  expires: never

Note that the information under "General key info" is coming from the keyring files on your computer. If you run "gpg --card-status" on a computer whose keyring doesn't have your file yet, the last line will be ...

General key info..: [none]