Create a bootable USB flash drive for generating and managing PGP keys. The keys will be generated and stored, encrypted, on the drive but then also transferred to Yubikeys for general use. Unless a Yubikey is lost or damaged, use of the flash drive should be extremely limited, if it is used at all.
A master certifying and signing (CS) key will be created, then sub-key signing (S), encrypting (E), and authenticating (A) keys will be created and signed by the C key. The C key will be archived with a password to the flash drive as well as transferred to a Yubikey 4. The SE&A sub keys will also be archived to the flash drive as part of the C key but then transferred to a daily-use Yubikey 5 NFC. The private key components will be printed on paper using a laser printer via paperkey.
The C key will have a life of 10 years. Each sub key will have a life of 2 years.
All keys will use my common UIDs of: [email protected] and [email protected]
The flash drive, printed private keys, and Yubikey 4 will be stored in a safe place. They Yubikey 5 NFC will travel with me on my keychain.
Every time I generate new subkeys, it may be wise to reprint my private keys, but if I want to treat them as volatile then just having the ability to revoke them and generate new ones will be good enough.
The bootable flash drive will run Ubuntu 18.04 LTS server amd64. The root file system will be encrypted via LUKS using a password. Only packages required to perform the above activies will be installed and recorded, here.
Before installing, repartition the USB flash drive to use a GPT partition table, create a 200MB EFI system partition, create a 1GB Linux partition which will be /boot partition, and create the rest of the disk as a Linux partition. Then start the Ubuntu server installer and at the partitioning step, format the EFI system partition as such, format the /boot partition with ext4, and configure the last partition as a physical volume for encryption. Within the encrypted volume setup, configure a password to decrypt and create a single partition to be the root file system and format it with ext4.
After install is complete, perform an update, then install:
- libykpers-1-1 (to get yubikey udev rules)
- cups (so we can print)
- paperkey (for easy printing for archival)
First create a certifying and signing RSA-4096 keypair (this is not my actual key info, just a representation):
$ gpg --full-generate-key
gpg (GnuPG) 2.2.12; Copyright (C) 2018 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.
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 10y
Key expires at Sun 17 Feb 2030 02:08:51 PM EST
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: Andrew Bradford
Email address: [email protected]
Comment:
You selected this USER-ID:
"Andrew Bradford <[email protected]>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 0CCE890A32249506 marked as ultimately trusted
gpg: directory '/home/andrew/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/andrew/.gnupg/openpgp-revocs.d/9E650DF1D57679A2EEC461620CCE890A32249506.rev'
public and secret key created and signed.
Note that this key cannot be used for encryption. You may want to use
the command "--edit-key" to generate a subkey for this purpose.
pub rsa4096 2020-02-20 [SC] [expires: 2030-02-17]
9E650DF1D57679A2EEC461620CCE890A32249506
uid Andrew Bradford <[email protected]>
Now create the (E) encrypting and (S) signing keys:
$ gpg --edit-key 9E650DF1D57679A2EEC461620CCE890A32249506
gpg (GnuPG) 2.2.12; Copyright (C) 2018 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.
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2030-02-17
sec rsa4096/0CCE890A32249506
created: 2020-02-20 expires: 2030-02-17 usage: SC
trust: ultimate validity: ultimate
[ultimate] (1). Andrew Bradford <[email protected]>
gpg> addkey
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
Your selection? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 2y
Key expires at Sat 19 Feb 2022 02:14:05 PM EST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
sec rsa4096/0CCE890A32249506
created: 2020-02-20 expires: 2030-02-17 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/70324A9C2EBB90AE
created: 2020-02-20 expires: 2022-02-19 usage: E
[ultimate] (1). Andrew Bradford <[email protected]>
gpg> addkey
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 2y
Key expires at Sat 19 Feb 2022 02:14:47 PM EST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
sec rsa4096/0CCE890A32249506
created: 2020-02-20 expires: 2030-02-17 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/70324A9C2EBB90AE
created: 2020-02-20 expires: 2022-02-19 usage: E
ssb rsa4096/B240F62D893A7D1C
created: 2020-02-20 expires: 2022-02-19 usage: S
[ultimate] (1). Andrew Bradford <[email protected]>
gpg> quit
Save changes? (y/N) y
Now finally create the (A) authentication key, using the expert mode:
$ gpg --expert --edit-key 9E650DF1D57679A2EEC461620CCE890A32249506
gpg (GnuPG) 2.2.12; Copyright (C) 2018 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/0CCE890A32249506
created: 2020-02-20 expires: 2030-02-17 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/70324A9C2EBB90AE
created: 2020-02-20 expires: 2022-02-19 usage: E
ssb rsa4096/B240F62D893A7D1C
created: 2020-02-20 expires: 2022-02-19 usage: S
[ultimate] (1). Andrew Bradford <[email protected]>
gpg> addkey
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(10) ECC (sign only)
(11) ECC (set your own capabilities)
(12) ECC (encrypt only)
(13) Existing key
Your selection? 8
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? S
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Encrypt
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? E
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions:
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? A
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Authenticate
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? Q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 2y
Key expires at Sat 19 Feb 2022 02:19:45 PM EST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
sec rsa4096/0CCE890A32249506
created: 2020-02-20 expires: 2030-02-17 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/70324A9C2EBB90AE
created: 2020-02-20 expires: 2022-02-19 usage: E
ssb rsa4096/B240F62D893A7D1C
created: 2020-02-20 expires: 2022-02-19 usage: S
ssb rsa4096/33EF6796E27F98C4
created: 2020-02-20 expires: 2022-02-19 usage: A
[ultimate] (1). Andrew Bradford <[email protected]>
gpg> quit
Save changes? (y/N) y
Add my other email address to my keys. At the end of this it'll show the new UID as "unknown" trust level but once you save and exit gpg then the next time you start it it'll show as "ultimate" trust level as we expect:
$ gpg --edit-key 9E650DF1D57679A2EEC461620CCE890A32249506
gpg (GnuPG) 2.2.12; Copyright (C) 2018 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.
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2030-02-17
sec rsa4096/0CCE890A32249506
created: 2020-02-20 expires: 2030-02-17 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/70324A9C2EBB90AE
created: 2020-02-20 expires: 2022-02-19 usage: E
ssb rsa4096/B240F62D893A7D1C
created: 2020-02-20 expires: 2022-02-19 usage: S
ssb rsa4096/33EF6796E27F98C4
created: 2020-02-20 expires: 2022-02-19 usage: A
[ultimate] (1). Andrew Bradford <[email protected]>
gpg> adduid
Real name: Andrew Bradford
Email address: [email protected]
Comment:
You selected this USER-ID:
"Andrew Bradford <[email protected]>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
sec rsa4096/0CCE890A32249506
created: 2020-02-20 expires: 2030-02-17 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/70324A9C2EBB90AE
created: 2020-02-20 expires: 2022-02-19 usage: E
ssb rsa4096/B240F62D893A7D1C
created: 2020-02-20 expires: 2022-02-19 usage: S
ssb rsa4096/33EF6796E27F98C4
created: 2020-02-20 expires: 2022-02-19 usage: A
[ultimate] (1) Andrew Bradford <[email protected]>
[ unknown] (2). Andrew Bradford <[email protected]>
gpg> q
Save changes? (y/N) y
Export the public keys to a file at ~/gpg-key.public and the secret keys to a file at ~/gpg-key.private so that when we transfer them to the Yubikeys (which by default deletes the local key) that we have a backup:
$ gpg --export --output ~/gpg-public.asc
$ gpg --export-secret-keys --output ~/gpg-private.asc
Verify that gpg still knows about our keys:
$ gpg --list-keys
gpg --list-keys
/home/bradfa/.gnupg/pubring.kbx
-------------------------------
pub rsa4096 2020-10-17 [SC] [expires: 2030-10-15]
B2B3A55CC4DCC1CD2624B82CBA3960057EF21997
uid [ultimate] Andrew Bradford <[email protected]>
uid [ultimate] Andrew Bradford <[email protected]>
sub rsa4096 2020-10-17 [E] [expires: 2022-10-17]
sub rsa4096 2020-10-17 [S] [expires: 2022-10-17]
sub rsa4096 2020-10-17 [A] [expires: 2022-10-17]
Generate a revocation certificate text file, in case we ever need to revoke our certifying key in the future. Since you need access to the key to create the revocation cert, let's do it now:
$ gpg --output ~/gpg-revocation-cert.txt --gen-revoke B2B3A55CC4DCC1CD2624B82CBA3960057EF21997
sec rsa4096/BA3960057EF21997 2020-10-17 Andrew Bradford <[email protected]>
Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
0 = No reason specified
1 = Key has been compromised
2 = Key is superseded
3 = Key is no longer used
Q = Cancel
(Probably you want to select 1 here)
Your decision? 0
Enter an optional description; end it with an empty line:
> General revocation certificate.
>
Reason for revocation: No reason specified
General revocation certificate.
Is this okay? (y/N) y
ASCII armored output forced.
Revocation certificate created.
Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable. But have some caution: The print system of
your machine might store the data and make it available to others!
You should now have 3 files in your home directory related to our current key work:
$ ls
gpg-private.asc gpg-public.asc gpg-revocation-cert.txt
Connect the Yubikey 4 and verify that gnupg can access it:
$ gpg --card-status
Reader ...........: 1050:0407:X:0
Application ID ...: <redacted>
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: <redacted>
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa2048 rsa2048 rsa2048
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]
Perform a factory reset of your Yubikey 4's OpenPGP applet:
$ gpg --card-edit
Reader ...........: 1050:0407:X:0
Application ID ...: <redacted>
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: <redacted>
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa2048 rsa2048 rsa2048
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]
gpg/card> admin
Admin commands are allowed
gpg/card> factory-reset
gpg: OpenPGP card no. <redacted> detected
gpg: Note: This command destroys all keys stored on the card!
Continue? (y/N) y
Really do a factory reset? (enter "yes") yes
gpg/card> quit
Set the Yubikey 4 admin and normal PIN since we do not want to use the default PIN of 123456
or the
default Admin PIN of 12345678
. You'll have to enter the current (default) admin and user PIN when
prompted as well as double entries of the new PINs you're selecting:
$ gpg --card-edit
Reader ...........: 1050:0407:X:0
Application ID ...: <redacted>
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: <redacted>
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa2048 rsa2048 rsa2048
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]
gpg/card> admin
Admin commands are allowed
gpg/card> passwd
gpg: OpenPGP card no. <redacted> detected
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Your selection? 3
PIN changed.
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Your selection? 1
PIN changed.
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Your selection? Q
gpg/card> quit
If you want to require a code in order to return the Yubikey OpenPGP applet back to factory defaults in the future, also set a "Reset Code" but be warned that this is dangerous as you may lock yourself out of being able to use this Yubikey for OpenPGP uses in the future. I am not setting one.
Now, transfer your primary [CS] key to the Yubikey 4, enter the admin PIN you just created when prompted:
$ gpg --edit-key B2B3A55CC4DCC1CD2624B82CBA3960057EF21997
gpg (GnuPG) 2.2.12; Copyright (C) 2018 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/BA3960057EF21997
created: 2020-10-17 expires: 2030-10-15 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/C59A68A9AD2E836B
created: 2020-10-17 expires: 2022-10-17 usage: E
ssb rsa4096/835D994D83AA7699
created: 2020-10-17 expires: 2022-10-17 usage: S
ssb rsa4096/0BDC91EE02BEE34C
created: 2020-10-17 expires: 2022-10-17 usage: A
[ultimate] (1). Andrew Bradford <[email protected]>
[ultimate] (2) Andrew Bradford <[email protected]>
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
sec rsa4096/BA3960057EF21997
created: 2020-10-17 expires: 2030-10-15 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/C59A68A9AD2E836B
created: 2020-10-17 expires: 2022-10-17 usage: E
ssb rsa4096/835D994D83AA7699
created: 2020-10-17 expires: 2022-10-17 usage: S
ssb rsa4096/0BDC91EE02BEE34C
created: 2020-10-17 expires: 2022-10-17 usage: A
[ultimate] (1). Andrew Bradford <[email protected]>
[ultimate] (2) Andrew Bradford <[email protected]>
gpg> quit
Save changes? (y/N) y
Now when you have gnupg show you your keys, it'll say "pub" instead of "sec" for your primary key, since the key is no longer stored locally by gnupg, it's on your Yubikey 4 now:
$ gpg --list-keys
/home/bradfa/.gnupg/pubring.kbx
-------------------------------
pub rsa4096 2020-10-17 [SC] [expires: 2030-10-15]
B2B3A55CC4DCC1CD2624B82CBA3960057EF21997
uid [ultimate] Andrew Bradford <[email protected]>
uid [ultimate] Andrew Bradford <[email protected]>
sub rsa4096 2020-10-17 [E] [expires: 2022-10-17]
sub rsa4096 2020-10-17 [S] [expires: 2022-10-17]
sub rsa4096 2020-10-17 [A] [expires: 2022-10-17]
You can show the keys on the Yubikey. It's a little confusing but the way gnupg shows the primary
key is to also list all subkeys even though the subkeys aren't on the card. It's only the keys which have the >
after their type which are actually on the card:
$ gpg --card-status
Reader ...........: 1050:0407:X:0
Application ID ...: <redacted>
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: <redacted>
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: B2B3 A55C C4DC C1CD 2624 B82C BA39 6005 7EF2 1997
created ....: 2020-10-17 17:05:37
Encryption key....: [none]
Authentication key: [none]
General key info..: pub rsa4096/BA3960057EF21997 2020-10-17 Andrew Bradford <[email protected]>
sec> rsa4096/BA3960057EF21997 created: 2020-10-17 expires: 2030-10-15
card-no: 0006 07756688
ssb rsa4096/C59A68A9AD2E836B created: 2020-10-17 expires: 2022-10-17
ssb rsa4096/835D994D83AA7699 created: 2020-10-17 expires: 2022-10-17
ssb rsa4096/0BDC91EE02BEE34C created: 2020-10-17 expires: 2022-10-17
You can verify that the 3 subkeys are still local by looking at the size and last modification time of the gnupg private key files, one key will be much smaller than the others now, that's the primary key which we've sent to the Yubikey:
$ ls .gnupg/private-keys-v1.d/ -l
total 16
-rw------- 1 bradfa bradfa 2072 Oct 17 13:09 5EDDEDFB5985D9E5A7DE91AF22D1E22024D3BD49.key
-rw------- 1 bradfa bradfa 2056 Oct 17 13:07 7A51300C1DE24F0223852BDE93C0F6EFAF395A86.key
-rw------- 1 bradfa bradfa 615 Oct 17 14:00 CD64AECB7DF245DB35A4D0A52E878498EBF49CD9.key
-rw------- 1 bradfa bradfa 2072 Oct 17 13:06 EC31B67E33245B2CCF1400D76DFD731259F986CF.key
Publish your primary key to a keyserver, such as https://pgp.mit.edu/. To get the ASCII armoured public key for uploading to the key server:
gpg --armour --export B2B3A55CC4DCC1CD2624B82CBA3960057EF21997
<and you'll get a lot of output that you can copy-paste to the keyserver's UI>
The public key holds info about all your subkeys as well as any signatures you've received from others, so it can be kind of large. You can even embed a photo of yourself into it, although I'm not going to do that.
Don't be afraid to send your public key to lots of places, maybe multiple key servers. Just in case one of the keyservers dies, as your public key is not within your Yubikeys! Only the secret crypto parts of your keys are in the Yubikeys, any signatures you've received from others on your public key are not stored in the Yubikeys. You probably should have 1 main key server where you store your public key and then backups stored in other places, or on multiple machines, or whatnot. It's just annoying to update all of them if someone else signs your key or if you need to revoke a subkey and/or generate new subkeys.
Now you can set the Yubikey 4 OpenPGP card info on the card as you see fit, and set the "url" to be the address which you've uploaded your key to the keyserver, which the keyserver will tell you when you've successfully completed the upload:
$ gpg --card-edit
Reader ...........: 1050:0407:X:0
Application ID ...: <redacted>
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: <redacted>
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: B2B3 A55C C4DC C1CD 2624 B82C BA39 6005 7EF2 1997
created ....: 2020-10-17 17:05:37
Encryption key....: [none]
Authentication key: [none]
General key info..:
pub rsa4096/BA3960057EF21997 2020-10-17 Andrew Bradford <[email protected]>
sec> rsa4096/BA3960057EF21997 created: 2020-10-17 expires: 2030-10-15
card-no: 0006 07756688
ssb rsa4096/C59A68A9AD2E836B created: 2020-10-17 expires: 2022-10-17
ssb rsa4096/835D994D83AA7699 created: 2020-10-17 expires: 2022-10-17
ssb rsa4096/0BDC91EE02BEE34C created: 2020-10-17 expires: 2022-10-17
gpg/card> admin
Admin commands are allowed
gpg/card> name
Cardholder's surname: Bradford
Cardholder's given name: Andrew
gpg/card> forcesig
gpg/card> url
URL to retrieve public key: https://pgp.mit.edu/pks/lookup?op=get&search=0xBA3960057EF21997
gpg/card> quit
Now we can repeat the process of setting up the Yubikey but with our Yubikey 5. Do the factory reset,
set the admin and normal PIN, and then we're ready to "toggle" each of the subkeys using the "key"
command within gpg --edit-key <keyid>
(no arguments selects no keys, key 1
toggles selection of
the first key, etc) and send each of the subkeys to the card.
Finally, you should be in a situation where gnupg knows about all of your keys (the primary, plus the 3 subkeys) but none are local to gnupg on disk any longer (except the backups we made).
Now you'll need to re-import the backed up keys, this way you'll have a USB flash drive which can do everything, a Yubikey 4 which can be used for key signings and other once-in-a-while tasks, and a Yubikey 5 that goes with you everywhere. If the flash drive dies, you still have a hard copy print out and the Yubikey 4 to perform all operations. If the Yubikey 4 dies, you can make a new one using the USB flash drive. If the Yubikey 5 dies, you can create a new one or revoke the keys and create new "daily use" keys from the flash drive and/or the Yubikey 4.
To make printable versions of our secret keys, use paperkey, like:
$ paperkey --secret-key gpg-private.asc | lpr
To reimport the keys we saved off, first delete gnupg's concept of them:
$ gpg --delete-secret-keys B2B3A55CC4DCC1CD2624B82CBA3960057EF21997
gpg (GnuPG) 2.2.12; Copyright (C) 2018 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.
sec rsa4096/BA3960057EF21997 2020-10-17 Andrew Bradford <[email protected]>
Delete this key from the keyring? (y/N) y
This is a secret key! - really delete? (y/N) y
And now the public keys:
$ gpg --delete-keys B2B3A55CC4DCC1CD2624B82CBA3960057EF21997
gpg (GnuPG) 2.2.12; Copyright (C) 2018 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.
pub rsa4096/BA3960057EF21997 2020-10-17 Andrew Bradford <[email protected]>
Delete this key from the keyring? (y/N) y
And now import our saved off private key:
$ gpg --import gpg-private.key
gpg: key BA3960057EF21997: public key "Andrew Bradford <[email protected]>" imported
gpg: To migrate 'secring.gpg', with each smartcard, run: gpg --card-status
gpg: key BA3960057EF21997: secret key imported
gpg: Total number processed: 1
gpg: imported: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
And then mark the newly imported key as ultimately trusted:
$ gpg --edit-key B2B3A55CC4DCC1CD2624B82CBA3960057EF21997
gpg (GnuPG) 2.2.12; Copyright (C) 2018 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 subkeys are available.
pub rsa4096/BA3960057EF21997
created: 2020-10-17 expires: 2030-10-15 usage: SC
trust: unknown validity: unknown
sub rsa4096/C59A68A9AD2E836B
created: 2020-10-17 expires: 2022-10-17 usage: E
ssb rsa4096/835D994D83AA7699
created: 2020-10-17 expires: 2022-10-17 usage: S
ssb rsa4096/0BDC91EE02BEE34C
created: 2020-10-17 expires: 2022-10-17 usage: A
[ unknown] (1). Andrew Bradford <[email protected]>
[ unknown] (2) Andrew Bradford <[email protected]>
gpg> trust
pub rsa4096/BA3960057EF21997
created: 2020-10-17 expires: 2030-10-15 usage: SC
trust: unknown validity: unknown
sub rsa4096/C59A68A9AD2E836B
created: 2020-10-17 expires: 2022-10-17 usage: E
ssb rsa4096/835D994D83AA7699
created: 2020-10-17 expires: 2022-10-17 usage: S
ssb rsa4096/0BDC91EE02BEE34C
created: 2020-10-17 expires: 2022-10-17 usage: A
[ unknown] (1). Andrew Bradford <[email protected]>
[ unknown] (2) Andrew Bradford <[email protected]>
Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)
1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y
pub rsa4096/BA3960057EF21997
created: 2020-10-17 expires: 2030-10-15 usage: SC
trust: ultimate validity: unknown
sub rsa4096/C59A68A9AD2E836B
created: 2020-10-17 expires: 2022-10-17 usage: E
ssb rsa4096/835D994D83AA7699
created: 2020-10-17 expires: 2022-10-17 usage: S
ssb rsa4096/0BDC91EE02BEE34C
created: 2020-10-17 expires: 2022-10-17 usage: A
[ unknown] (1). Andrew Bradford <[email protected]>
[ unknown] (2) Andrew Bradford <[email protected]>
Please note that the shown key validity is not necessarily correct
unless you restart the program.
gpg> quit
TODO: Make sure all the example keys match as this has been written over a year's time across multiple different systems using fake demonstration keys.