I have moved to a new OpenPGP key. There are many tutorials and blog posts on GnuPG key generation around, but none of them matched exactly the setup I wanted to have. So I wrote down the steps I took, to remember them if I need to in the future. Briefly my requirements were as follows:
- The new master GnuPG key is on an USB stick.
- The USB stick is only ever used on an offline computer.
- There are subkeys stored on a YubiKey NEO smartcard for daily use.
- I want to generate the subkeys using GnuPG so I have a backup.
- Some non-default hash/cipher preferences encoded into the public key.
After writing down the notes below, I posted about how to create a small JPEG image to embed in my OpenPGP key. I was planning to go live with the first key I generated, however as was gently pointed out to me, the JPEG image I generated was not optimal (too low quality and not sufficiently compressed). I have decided to retake the photo so I have a color image as a basis for size optimization. I don’t want to postpone using the new key though, so I stepped through all of these steps again (except adding the photo) to get a new key. This is why the notes below are for a key 1C5C4717 that is now revoked. My new real key is 54265E8C. I will add the photo to my 54265E8C key once I have a JPEG file that I’m happy with.
Offline machine
The offline machine setup I use is a Live CD on a machine that is physically well protected. I’m using the Debian Live CD version 7.5.0 GNOME Desktop. The password for the auto-logged in user is “live” which you need if the screen-saver kicks in. Configure the keyboard layout if you need to. Insert an USB memory stick. I’m using a VFAT filesystem to keep things simple; and for this writeup it happened to be mounted as /media/FA21-BEC7
so you will have to replace that path with something that points to your USB stick. Open a terminal since the rest of this writeup will be done from a terminal window.
GnuPG configuration
Set your GnuPG home directory to point at the USB memory device. You will need to do this in every terminal windows you open that you want to use GnuPG in.
user@debian:~$ export GNUPGHOME=/media/FA21-BEC7/gnupghome user@debian:~$ mkdir $GNUPGHOME user@debian:~$
The GnuPG defaults (as of version 1.4.16) to rank SHA1 higher than SHA384, SHA512, and SHA224 in the default hash preference list. To be precise, the default hash preference order is SHA256, SHA1, SHA384, SHA512, SHA224. I consider SHA1 broken so I don’t advertise it all, although I believe that will not prevent some implementations of using SHA1 anyway since it is the mandatory to implement hash algorithm. Regarding symmetric ciphers, the default order is AES256, AES192, AES128, CAST5, 3DES. I don’t like ciphers with 64-bit block lengths, so I don’t advertise them but similarily, I believe this will not prevent some implementations of using CAST5 or 3DES anyway. I also advertise support for Twofish and Camellia in case someone wants to use them, they are 128-bit block length and relatively modern ciphers after all. The “default-preference-list” keyword is used to override the default settings, which will be recorded into any newly generated keys.
GnuPG self-sign keys with SHA1 by default, and I prefer to use a member of the SHA2 family, hence the “cert-digest-algo” keyword. Further down below we will use the GnuPG Agent to talk to the smartcard, so configure GnuPG to use it with the “use-agent” keyword. GnuPG prints ugly warning messages about locking (gpg: DBG: locking for `/media/FA21-BEC7/gnupghome/secring.gpg.lock' done via O_EXCL
), presumably because of the VFAT filesystem, so I use “lock-never” to silence that.
user@debian:~$ cat > $GNUPGHOME/gpg.conf default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAMELLIA256 CAMELLIA192 CAMELLIA128 TWOFISH cert-digest-algo SHA512 use-agent lock-never user@debian:~$
Generate master key
Below I will use a 3744 bit RSA key, where the key size is selected based on the assumption that people will focus efforts to crack RSA keys on the usual power-of-two key sizes. I have chosen to not generate an encryption key, since I will use subkeys on a smartcard. With my old B565716F key I noticed that sometimes people will encrypt to my main encryption key even though I have encryption subkeys. Presumably this happens due to implementation flaws or user configuration mistakes. It could happen “intentionally” if someone had a public key from me with an expired subkeys but not expired main keys. This could be a reason to use the same expiration day for all your keys. Still, I chose to not generate an encryption key at all at this point. For additional protection, I’m using a passphrase on the key.
user@debian:~$ gpg --gen-key gpg (GnuPG) 1.4.12; Copyright (C) 2012 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. gpg: keyring `/media/FA21-BEC7/gnupghome/secring.gpg' created gpg: keyring `/media/FA21-BEC7/gnupghome/pubring.gpg' created 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? (2048) 3744 Requested keysize is 3744 bits Please specify how long the key should be valid. 0 = key does not expire= key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) 100 Key expires at Fri 26 Sep 2014 10:50:22 PM UTC Is this correct? (y/N) y You need a user ID to identify your key; the software constructs the user ID from the Real Name, Comment and Email Address in this form: "Heinrich Heine (Der Dichter) " Real name: Simon Josefsson Email address: simon@josefsson.org Comment: You selected this USER-ID: "Simon Josefsson " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o You need a Passphrase to protect your secret key. 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: /media/FA21-BEC7/gnupghome/trustdb.gpg: trustdb created gpg: key 1C5C4717 marked as ultimately trusted public and secret key created and signed. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u gpg: next trustdb check due at 2014-09-26 pub 3744R/1C5C4717 2014-06-18 [expires: 2014-09-26] Key fingerprint = EF0A 1996 7B3B 4BAD 9D5C A97F 1A44 08DD 1C5C 4717 uid Simon Josefsson 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. user@debian:~$
Add photo
I’m in the process of creating a better JPEG photo, so I skipped this step for my new key. However the notes here are correct anyway.
user@debian:~$ gpg --edit-key 1C5C4717 gpg (GnuPG) 1.4.12; Copyright (C) 2012 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. pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: ultimate [ultimate] (1). Simon Josefssongpg> addphoto Pick an image to use for your photo ID. The image must be a JPEG file. Remember that the image is stored within your public key. If you use a very large picture, your key will become very large as well! Keeping the image close to 240x288 is a good size to use. Enter JPEG filename for photo ID: /media/FA21-BEC7/simon-gpg.jpg Is this photo correct (y/N/q)? y You need a passphrase to unlock the secret key for user: "Simon Josefsson " 3744-bit RSA key, ID 1C5C4717, created 2014-06-18 pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: ultimate [ultimate] (1). Simon Josefsson [ unknown] (2) [jpeg image of size 6048] gpg> save user@debian:~$
Add another identity
Most people have multiple email addresses, and this needs to be reflected in the GnuPG key. Use the primary
command to specify your main User ID.
user@debian:~$ gpg --edit-key 1C5C4717 gpg (GnuPG) 1.4.12; Copyright (C) 2012 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. pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: ultimate [ultimate] (1). Simon Josefsson[ultimate] (2) [jpeg image of size 6048] gpg> adduid Real name: Simon Josefsson Email address: simon@yubico.com Comment: You selected this USER-ID: "Simon Josefsson " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o You need a passphrase to unlock the secret key for user: "Simon Josefsson " 3744-bit RSA key, ID 1C5C4717, created 2014-06-18 pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: ultimate [ultimate] (1) Simon Josefsson [ultimate] (2) [jpeg image of size 6048] [ unknown] (3). Simon Josefsson gpg> uid 1 pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: ultimate [ultimate] (1)* Simon Josefsson [ultimate] (2) [jpeg image of size 6048] [ unknown] (3). Simon Josefsson gpg> primary You need a passphrase to unlock the secret key for user: "Simon Josefsson " 3744-bit RSA key, ID 1C5C4717, created 2014-06-18 pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: ultimate [ultimate] (1)* Simon Josefsson [ultimate] (2) [jpeg image of size 6048] [ unknown] (3) Simon Josefsson gpg> save user@debian:~$
Create a revocation certificate
It is good practice to generate a revocation certificate in case you lose your key. Store this in a safe place, possibly printed out on paper.
user@debian:~$ gpg --output $GNUPGHOME/../revocation-certificate.txt --gen-revoke 1C5C4717 sec 3744R/1C5C4717 2014-06-18 Simon JosefssonCreate 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? 1 Enter an optional description; end it with an empty line: > Created during key creation, emergency use only. > Reason for revocation: Key has been compromised Created during key creation, emergency use only. Is this okay? (y/N) y You need a passphrase to unlock the secret key for user: "Simon Josefsson " 3744-bit RSA key, ID 1C5C4717, created 2014-06-18 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! user@debian:~$
Make a backup of the master key
To have an easy way to move back and forward in time in GnuPG, I both export the key to a stable data format and keep a backup of the actual GnuPG home directory.
user@debian:~$ gpg -a --export-secret-keys 1C5C4717 > $GNUPGHOME/../masterkey.txt user@debian:~$ cp -a $GNUPGHOME $GNUPGHOME-backup-masterkey user@debian:~$
Create subkeys
Now I will generate three keys that will go onto the smartcard. I have chosen to generate these using GnuPG and then move the keys onto the smartcards, instead of generating the keys directly on the card. The difference is that with this approach, I get a backup of the keys and can import them to another key in the future if I need to.
Each key has its own purpose: Signature, Encryption, and Authentication. Smartcards typically have limitation on key sizes, so I select 2048 as a widely supported size. Expert mode is required to generate authentication subkeys.
user@debian:~$ gpg --expert --edit-key 1C5C4717 gpg (GnuPG) 1.4.12; Copyright (C) 2012 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. pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: ultimate [ultimate] (1). Simon Josefsson[ultimate] (2) [jpeg image of size 6048] [ultimate] (3) Simon Josefsson gpg> addkey Key is protected. You need a passphrase to unlock the secret key for user: "Simon Josefsson " 3744-bit RSA key, ID 1C5C4717, created 2014-06-18 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) Your selection? 4 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) 100 Key expires at Fri 26 Sep 2014 11:03:16 PM UTC 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. ..+++++ ....+++++ pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: ultimate sub 2048R/72D5245B created: 2014-06-18 expires: 2014-09-26 usage: S [ultimate] (1). Simon Josefsson [ultimate] (2) [jpeg image of size 6048] [ultimate] (3) Simon Josefsson gpg> addkey Key is protected. You need a passphrase to unlock the secret key for user: "Simon Josefsson " 3744-bit RSA key, ID 1C5C4717, created 2014-06-18 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) Your selection? 6 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) 100 Key expires at Fri 26 Sep 2014 11:03:31 PM UTC 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. ......+++++ Not enough random bytes available. Please do some other work to give the OS a chance to collect more entropy! (Need 7 more bytes) .+++++ pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: ultimate sub 2048R/72D5245B created: 2014-06-18 expires: 2014-09-26 usage: S sub 2048R/A11F46D2 created: 2014-06-18 expires: 2014-09-26 usage: E [ultimate] (1). Simon Josefsson [ultimate] (2) [jpeg image of size 6048] [ultimate] (3) Simon Josefsson gpg> addkey Key is protected. You need a passphrase to unlock the secret key for user: "Simon Josefsson " 3744-bit RSA key, ID 1C5C4717, created 2014-06-18 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) 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? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) 100 Key expires at Fri 26 Sep 2014 11:03:59 PM UTC 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. +++++ Not enough random bytes available. Please do some other work to give the OS a chance to collect more entropy! (Need 56 more bytes) +++++ pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: ultimate sub 2048R/72D5245B created: 2014-06-18 expires: 2014-09-26 usage: S sub 2048R/A11F46D2 created: 2014-06-18 expires: 2014-09-26 usage: E sub 2048R/D6987A02 created: 2014-06-18 expires: 2014-09-26 usage: A [ultimate] (1). Simon Josefsson [ultimate] (2) [jpeg image of size 6048] [ultimate] (3) Simon Josefsson gpg> save user@debian:~$
Export subkeys for backup
This is a good time to save a restore point for your key. Note in the output of --list-secret-keys
the keywords sec and ssb which means the main key and the subkeys are available. If the secret keyring contained only stubs, it would be sec> and sec#.
user@debian:~$ gpg --list-keys /media/FA21-BEC7/gnupghome/pubring.gpg -------------------------------------- pub 3744R/1C5C4717 2014-06-18 [expires: 2014-09-26] uid Simon Josefssonuid [jpeg image of size 6048] uid Simon Josefsson sub 2048R/72D5245B 2014-06-18 [expires: 2014-09-26] sub 2048R/A11F46D2 2014-06-18 [expires: 2014-09-26] sub 2048R/D6987A02 2014-06-18 [expires: 2014-09-26] user@debian:~$ gpg --list-secret-keys /media/FA21-BEC7/gnupghome/secring.gpg -------------------------------------- sec 3744R/1C5C4717 2014-06-18 [expires: 2014-09-26] uid Simon Josefsson uid [jpeg image of size 6048] uid Simon Josefsson ssb 2048R/72D5245B 2014-06-18 ssb 2048R/A11F46D2 2014-06-18 ssb 2048R/D6987A02 2014-06-18 user@debian:~$ gpg -a --export-secret-keys 1C5C4717 > $GNUPGHOME/../mastersubkeys.txt user@debian:~$ gpg -a --export-secret-subkeys 1C5C4717 > $GNUPGHOME/../subkeys.txt user@debian:~$ cp -a $GNUPGHOME $GNUPGHOME-backup-mastersubkeys user@debian:~$
Configure machine for smartcards
The YubiKey NEO requires that RSA keys are imported with some additional parameters, used for CRT speedups. This was fixed in GnuPG 2.0.22. Unfortunately, it is not fixed in GnuPG 1.x. However, GnuPG 1.x can use gpg-agent and scdaemon from GnuPG to communicate with the smartcard. So let’s work around the limitation in GnuPG 1.x by installing parts from GnuPG 2.x and use those.
You will need to install the following packages: gnupg-agent, libpth20, pinentry-curses, libccid, pcscd, scdaemon, libksba8. Make sure that scdaemon is version 2.0.22 or later (get it from backports). I downloaded these packages and put them on the USB stick.
Unfortunately, libccid in Debian is a bit outdated, and does not contain the USB device vendor/product ID in /etc/libccid_Info.plist. You will need to manually add this, and restart pcscd.
user@debian:~$ sudo gedit /etc/libccid_Info.plist
user@debian:~$ sudo service pcscd restart
Start gnupg-agent and setup the environment variable for this session:
user@debian:~$ gpg-agent --daemon gpg-agent[22556]: directory `/media/FA21-BEC7/gnupghome/private-keys-v1.d' created GPG_AGENT_INFO=/tmp/gpg-wGji5C/S.gpg-agent:22557:1; export GPG_AGENT_INFO; gpg-agent[22557]: gpg-agent (GnuPG) 2.0.22 started user@debian:~$ GPG_AGENT_INFO=/tmp/gpg-wGji5C/S.gpg-agent:22557:1; export GPG_AGENT_INFO; user@debian:~$
Prepare YubiKey NEO
Make sure you have a recent firmware version, 3.1.8 or later; use lsusb -v
to find out.
Make sure the device is in OTP/CCID or CCID mode, use ykpersonalize -m82
from the YubiKey Personalization project to switch modes. There is a Debian package for it.
Make sure you have the OpenPGP applet loaded properly, otherwise see the YubiKey NEO OpenPGP applet project on installing it. You may want to set a proper Application ID, see herlo’s ssh-gpg-smartcard-config github repository for some hints.
Configure OpenPGP applet
This also changes the PIN and Admin codes.
user@debian:~$ gpg --card-edit Application ID ...: D2760001240102000060000000420000 Version ..........: 2.0 Manufacturer .....: unknown Serial number ....: 00000042 Name of cardholder: [not set] Language prefs ...: [not set] Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: 2048R 2048R 2048R Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 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. D2760001240102000060000000420000 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> name Cardholder's surname: Josefsson Cardholder's given name: Simon gpg/card> lang Language preferences: sv gpg/card> url URL to retrieve public key: https://josefsson.org/1c5c4717.txt gpg/card> sex Sex ((M)ale, (F)emale or space): m gpg/card> login Login data (account name): jas gpg/card> Application ID ...: D2760001240102000060000000420000 Version ..........: 2.0 Manufacturer .....: unknown Serial number ....: 00000042 Name of cardholder: Simon Josefsson Language prefs ...: sv Sex ..............: male URL of public key : https://josefsson.org/1c5c4717.txt Login data .......: jas Signature PIN ....: forced Key attributes ...: 2048R 2048R 2048R Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] gpg/card> quit user@debian:~$
Move subkeys to YubiKey NEO
Moving subkeys to a NEO is a destructive operation, so make sure you took backups of the subkeys as above. After this step, your GnuPG keyring will contain stubs for the subkeys.
user@debian:~$ gpg --edit-key 1C5C4717 gpg (GnuPG) 1.4.12; Copyright (C) 2012 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. pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: ultimate sub 2048R/72D5245B created: 2014-06-18 expires: 2014-09-26 usage: S sub 2048R/A11F46D2 created: 2014-06-18 expires: 2014-09-26 usage: E sub 2048R/D6987A02 created: 2014-06-18 expires: 2014-09-26 usage: A [ultimate] (1). Simon Josefsson[ultimate] (2) [jpeg image of size 6048] [ultimate] (3) Simon Josefsson gpg> toggle sec 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 ssb 2048R/72D5245B created: 2014-06-18 expires: never ssb 2048R/A11F46D2 created: 2014-06-18 expires: never ssb 2048R/D6987A02 created: 2014-06-18 expires: never (1) Simon Josefsson (2) [jpeg image of size 6048] (3) Simon Josefsson gpg> key 1 sec 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 ssb* 2048R/72D5245B created: 2014-06-18 expires: never ssb 2048R/A11F46D2 created: 2014-06-18 expires: never ssb 2048R/D6987A02 created: 2014-06-18 expires: never (1) Simon Josefsson (2) [jpeg image of size 6048] (3) Simon Josefsson gpg> keytocard Signature key ....: [none] Encryption key....: [none] Authentication key: [none] Please select where to store the key: (1) Signature key (3) Authentication key Your selection? 1 You need a passphrase to unlock the secret key for user: "Simon Josefsson " 2048-bit RSA key, ID 72D5245B, created 2014-06-18 sec 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 ssb* 2048R/72D5245B created: 2014-06-18 expires: never card-no: 0060 00000042 ssb 2048R/A11F46D2 created: 2014-06-18 expires: never ssb 2048R/D6987A02 created: 2014-06-18 expires: never (1) Simon Josefsson (2) [jpeg image of size 6048] (3) Simon Josefsson gpg> key 1 sec 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 ssb 2048R/72D5245B created: 2014-06-18 expires: never card-no: 0060 00000042 ssb 2048R/A11F46D2 created: 2014-06-18 expires: never ssb 2048R/D6987A02 created: 2014-06-18 expires: never (1) Simon Josefsson (2) [jpeg image of size 6048] (3) Simon Josefsson gpg> key 2 sec 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 ssb 2048R/72D5245B created: 2014-06-18 expires: never card-no: 0060 00000042 ssb* 2048R/A11F46D2 created: 2014-06-18 expires: never ssb 2048R/D6987A02 created: 2014-06-18 expires: never (1) Simon Josefsson (2) [jpeg image of size 6048] (3) Simon Josefsson gpg> keytocard Signature key ....: EF34 D1F7 95C0 3392 E52A 54FE DFF1 6372 72D5 245B Encryption key....: [none] Authentication key: [none] Please select where to store the key: (2) Encryption key Your selection? 2 You need a passphrase to unlock the secret key for user: "Simon Josefsson " 2048-bit RSA key, ID A11F46D2, created 2014-06-18 sec 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 ssb 2048R/72D5245B created: 2014-06-18 expires: never card-no: 0060 00000042 ssb* 2048R/A11F46D2 created: 2014-06-18 expires: never card-no: 0060 00000042 ssb 2048R/D6987A02 created: 2014-06-18 expires: never (1) Simon Josefsson (2) [jpeg image of size 6048] (3) Simon Josefsson gpg> key 2 sec 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 ssb 2048R/72D5245B created: 2014-06-18 expires: never card-no: 0060 00000042 ssb 2048R/A11F46D2 created: 2014-06-18 expires: never card-no: 0060 00000042 ssb 2048R/D6987A02 created: 2014-06-18 expires: never (1) Simon Josefsson (2) [jpeg image of size 6048] (3) Simon Josefsson gpg> key 3 sec 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 ssb 2048R/72D5245B created: 2014-06-18 expires: never card-no: 0060 00000042 ssb 2048R/A11F46D2 created: 2014-06-18 expires: never card-no: 0060 00000042 ssb* 2048R/D6987A02 created: 2014-06-18 expires: never (1) Simon Josefsson (2) [jpeg image of size 6048] (3) Simon Josefsson gpg> keytocard Signature key ....: EF34 D1F7 95C0 3392 E52A 54FE DFF1 6372 72D5 245B Encryption key....: E24D 5135 C2FC 905C 8995 ACD8 EC96 9E77 A11F 46D2 Authentication key: [none] Please select where to store the key: (3) Authentication key Your selection? 3 You need a passphrase to unlock the secret key for user: "Simon Josefsson " 2048-bit RSA key, ID D6987A02, created 2014-06-18 sec 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 ssb 2048R/72D5245B created: 2014-06-18 expires: never card-no: 0060 00000042 ssb 2048R/A11F46D2 created: 2014-06-18 expires: never card-no: 0060 00000042 ssb* 2048R/D6987A02 created: 2014-06-18 expires: never card-no: 0060 00000042 (1) Simon Josefsson (2) [jpeg image of size 6048] (3) Simon Josefsson gpg> save user@debian:~$
Take another backup
Can you tell yet that I like having backup options? Note that the subkeys are now marked ssb>
indicating they are stubs for a smartcard key.
user@debian:~$ gpg --list-secret-keys /media/FA21-BEC7/gnupghome/secring.gpg -------------------------------------- sec 3744R/1C5C4717 2014-06-18 [expires: 2014-09-26] uid Simon Josefssonuid [jpeg image of size 6048] uid Simon Josefsson ssb> 2048R/72D5245B 2014-06-18 ssb> 2048R/A11F46D2 2014-06-18 ssb> 2048R/D6987A02 2014-06-18 user@debian:~$ gpg -a --export-secret-keys 1C5C4717 > $GNUPGHOME/../masterstubs.txt user@debian:~$ gpg -a --export-secret-subkeys 1C5C4717 > $GNUPGHOME/../subkeysstubs.txt user@debian:~$ gpg -a --export 1C5C4717 > $GNUPGHOME/../publickey.txt user@debian:~$ cp -a $GNUPGHOME $GNUPGHOME-backup-masterstubs
Transfer to daily machine
Copy publickey.txt to your day-to-day laptop and import it.
jas@latte:~$ gpg --import < publickey.txt gpg: key 1C5C4717: public key "Simon Josefsson" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) jas@latte:~$
Insert the YubiKey NEO and generate secret key stubs:
jas@latte:~$ gpg --card-status Application ID ...: D2760001240102000060000000420000 Version ..........: 2.0 Manufacturer .....: unknown Serial number ....: 00000042 Name of cardholder: Simon Josefsson Language prefs ...: sv Sex ..............: male URL of public key : https://josefsson.org/1c5c4717.txt Login data .......: jas Signature PIN ....: forced Key attributes ...: 2048R 2048R 2048R Max. PIN lengths .: 0 0 0 PIN retry counter : 0 0 0 Signature counter : 0 Signature key ....: EF34 D1F7 95C0 3392 E52A 54FE DFF1 6372 72D5 245B created ....: 2014-06-18 23:03:16 Encryption key....: E24D 5135 C2FC 905C 8995 ACD8 EC96 9E77 A11F 46D2 created ....: 2014-06-18 23:03:31 Authentication key: 2768 2EF9 415C 19FC F0CC 9CA5 DA81 BA39 D698 7A02 created ....: 2014-06-18 23:03:59 General key info..: pub 2048R/72D5245B 2014-06-18 Simon Josefssonsec# 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 ssb> 2048R/72D5245B created: 2014-06-18 expires: 2014-09-26 card-no: 0060 00000042 ssb> 2048R/A11F46D2 created: 2014-06-18 expires: 2014-09-26 card-no: 0060 00000042 ssb> 2048R/D6987A02 created: 2014-06-18 expires: 2014-09-26 card-no: 0060 00000042 jas@latte:~$
Now you should have a offline master key with subkey stubs. Note that the master key is not available (sec#
) and the subkeys are stubs for smartcard keys (ssb>
).
jas@latte:~$ gpg --list-secret-keys 1c5c4717 sec# 3744R/1C5C4717 2014-06-18 [expires: 2014-09-26] uid Simon Josefssonuid [jpeg image of size 6048] uid Simon Josefsson ssb> 2048R/72D5245B 2014-06-18 [expires: 2014-09-26] ssb> 2048R/A11F46D2 2014-06-18 [expires: 2014-09-26] ssb> 2048R/D6987A02 2014-06-18 [expires: 2014-09-26] jas@latte:~$
Mark the key as ultimately trusted.
jas@latte:~$ gpg --edit-key 1c5c4717 gpg (GnuPG) 1.4.12; Copyright (C) 2012 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. pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: unknown validity: unknown sub 2048R/72D5245B created: 2014-06-18 expires: 2014-09-26 usage: S sub 2048R/A11F46D2 created: 2014-06-18 expires: 2014-09-26 usage: E sub 2048R/D6987A02 created: 2014-06-18 expires: 2014-09-26 usage: A [ unknown] (1). Simon Josefsson[ unknown] (2) [jpeg image of size 6048] [ unknown] (3) Simon Josefsson gpg> trust pub 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: unknown validity: unknown sub 2048R/72D5245B created: 2014-06-18 expires: 2014-09-26 usage: S sub 2048R/A11F46D2 created: 2014-06-18 expires: 2014-09-26 usage: E sub 2048R/D6987A02 created: 2014-06-18 expires: 2014-09-26 usage: A [ unknown] (1). Simon Josefsson [ unknown] (2) [jpeg image of size 6048] [ unknown] (3) Simon Josefsson 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 3744R/1C5C4717 created: 2014-06-18 expires: 2014-09-26 usage: SC trust: ultimate validity: unknown sub 2048R/72D5245B created: 2014-06-18 expires: 2014-09-26 usage: S sub 2048R/A11F46D2 created: 2014-06-18 expires: 2014-09-26 usage: E sub 2048R/D6987A02 created: 2014-06-18 expires: 2014-09-26 usage: A [ unknown] (1). Simon Josefsson [ unknown] (2) [jpeg image of size 6048] [ unknown] (3) Simon Josefsson Please note that the shown key validity is not necessarily correct unless you restart the program. gpg> quit jas@latte:~$
Signing keys
This needs to be done using your master key, since it is your certification key that will be used. So boot the Live CD and make the usual GnuPG configurations. Below I’m signing my own old key (0xB565716F) so the output may look a bit confusing with me signing my own key, but there is really two different keys involved here. The same process apply if you want to sign someone else’s key too.
Before signing the key, you need to put the public key on a USB stick and move it to the “secure” machine. On your laptop:
jas@latte:~$ gpg -a --export b565716f > /media/KINGSTON/b565716f.txt jas@latte:~$
On the disconnected machine:
user@debian:~$ gpg --import < /media/KINGSTON/b565716f.txt gpg: key B565716F: public key "Simon Josefsson" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u gpg: next trustdb check due at 2014-09-26 user@debian:~$ gpg --sign-key b565716f pub 1280R/B565716F created: 2002-05-05 expires: 2014-11-10 usage: SC trust: unknown validity: unknown sub 2048R/105E722E created: 2012-03-13 expires: 2014-11-10 usage: S sub 2048R/728AB82C created: 2012-03-13 expires: 2014-11-10 usage: E sub 2048R/9394F626 created: 2012-03-13 expires: 2014-11-10 usage: A sub 1280R/4D5D40AE created: 2002-05-05 expires: 2014-11-10 usage: E sub 1024R/09CC4670 created: 2006-03-18 expired: 2011-05-23 usage: A sub 1024R/AABB1F7B created: 2006-03-18 expired: 2011-05-23 usage: S sub 1024R/A14C401A created: 2006-03-18 expired: 2011-05-23 usage: E [ unknown] (1). Simon Josefsson [ unknown] (2) Simon Josefsson [ revoked] (3) Simon Josefsson Really sign all user IDs? (y/N) y User ID "Simon Josefsson " is revoked. Unable to sign. pub 1280R/B565716F created: 2002-05-05 expires: 2014-11-10 usage: SC trust: unknown validity: unknown Primary key fingerprint: 0424 D4EE 81A0 E3D1 19C6 F835 EDA2 1E94 B565 716F Simon Josefsson Simon Josefsson This key is due to expire on 2014-11-10. Are you sure that you want to sign this key with your key "Simon Josefsson " (1C5C4717) Really sign? (y/N) y You need a passphrase to unlock the secret key for user: "Simon Josefsson " 3744-bit RSA key, ID 1C5C4717, created 2014-06-18 user@debian:~$
Then export the newly signed key back to your laptop for further distribution.
user@debian:~$ gpg -a --export b565716f > /media/KINGSTON/signed-b565716f.txt user@debian:~$
On your laptop, either email it encrypted to the other person, or upload it to keyservers directly depending on your preference. By emailing it encrypted to the other person, they need to prove posession of the key before receiving your signature. In my case, I’m the other person, so I just import the signed key and then send the key:
jas@latte:~$ gpg --import < /media/KINGSTON/signed-b565716f.txt jas@latte:~$ gpg --send-keys b565716f
Key transition
Since I'm migrating from an key to a new, I sign my new key using my old key, and publish that signature on keyservers. This allows people to trust my new key more easily.
To let the world know about your key transition, I created a key transition statement. The transition statement should be signed by both keys. I created a new temporary GnuPG home directory and imported both master keys, and clearsigned the file. Note that I used "54265e8c!" to make GnuPG use the master key for signing rather than a subkey, which it would normally do.
user@debian:~$ export GNUPGHOME=/tmp/kts user@debian:~$ mkdir $GNUPGHOME user@debian:~$ gpg --import b565716f.txt gpg: WARNING: unsafe permissions on homedir `/tmp/kts' gpg: keyring `/tmp/kts/secring.gpg' created gpg: keyring `/tmp/kts/pubring.gpg' created gpg: key B565716F: secret key imported gpg: /tmp/kts/trustdb.gpg: trustdb created gpg: key B565716F: public key "Simon Josefsson" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) gpg: secret keys read: 1 gpg: secret keys imported: 1 user@debian:~$ gpg --import /media/FA21-AE97/secret-master-subkeys.txt gpg: WARNING: unsafe permissions on homedir `/tmp/kts' gpg: key 54265E8C: secret key imported gpg: key 54265E8C: public key "Simon Josefsson " imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) gpg: secret keys read: 1 gpg: secret keys imported: 1 user@debian:~$ cat key-transition-2014-06-22-unsigned.txt | gpg --clearsign --personal-digest-preferences "SHA512" --local-user b565716f --local-user 54265e8c! > key-transition-2014-06-22.txt gpg: WARNING: unsafe permissions on homedir `/tmp/kts' You need a passphrase to unlock the secret key for user: "Simon Josefsson " 3744-bit RSA key, ID 54265E8C, created 2014-06-22 You need a passphrase to unlock the secret key for user: "Simon Josefsson " 1280-bit RSA key, ID B565716F, created 2002-05-05 user@debian:~$
My statement is available as https://josefsson.org/key-transition-2014-06-22.txt if you want to download the signed text file directly. Feel free to base your own document on it, as I based mine on earlier examples.
According to the information I had, the Yubikey Neo was not supposed to support key import but only on-card generation. It looks like you proved that was wrong, and you seem to work for Yubico, so maybe you have more up-to-date information than I have: would you know, by chance, what exact key size the Yubikey Neo supports?
Also, since you are using a signature subkey, you could have generated your master key with only the certification capability. But contrary to encryption keys, this is not critical, and what is done is done anyway.
Thanks for feedback!
The YubiKey Neo supports key import, see the official documentation:
http://opensource.yubico.com/ykneo-openpgp/doc/KeyImport.html
I believe the NEO supports RSA key sizes of 512, 1024, and 2048. Importing RSA keys is pretty hard coded in the applet to 2048 bits, though, I think.
I prefer to have the Sign capability of the master key since I want to be able to sign statements using the master key as well. I signed the key transition document using my master key, not the subkey, for example.
/Simon
Okay, I tried it. The Yubikey Neo supports key up to 2048 bits, and it supports key imports since the version 1.0.5 of its PGP applet. In my case, I had to upgrade it, which is not really trivial since it relies on pieces of software I had to compile, and that suffer from a strange bug (gpshell does not look for libraries in /usr/local/lib, where libglobalplatform gets installed by default).
Anyway, it seems to work fine! Too bad it does not support 4096 bits keys, which means I will have to generate new subkeys and revoke my current ones…
I’m happy that it worked!
Streamlining the GlobalPlatform packages would be nice, I have debian packaging of them somewhere…
You should be able to use the YubiKey NEO Manager software to install the CAP file too: https://developers.yubico.com/libykneomgr/
The YubiKey NEO manager used to depend on Global Platform, but we found it difficult to work with so we integrated our own GP implementation into libykneomgr…
/Simon
Excellent, since ykneomgr is packaged in Debian, and its description clearly mentions that it can be used to install applets. It would be worth mentionning that in the PGP applet documentation, if you can pass the word. Also, that PGP applet, and the simple information that the Yubikey Neo can have PGP features at all, is very hard to find from the Yubico website, in fact I would never have found it without your comment.
Oh, one thing more, does ykneomgr set the serial number correctly when used to install the PGP applet?
No, ykneomgr just installs the CAP file. It should have a feature to specify the AID during installation instead of taking it from the CAP file. I’m not sure if it is a good idea for it to have OpenPGP-specific logic in it, so it can infer the AID from the serial number. But maybe..
/Simon
I am getting the following error:
gpg: selecting openpgp failed: ec=6.112
after executing:
root@virt:~# gpg –card-edit
Already tried to reload scdaemon.
The Vendor and Product ID’s were already in the libccid_Info.plist file.
I’m running the 3.20 firmware and Ubuntu 14.04.1 if that helps.
Are you sure this is GnuPG 2.0.22 or later? Try ‘gpg –version’. And that GnuPG is really talking to gpg-agent/scdaemon? This is a fairly generic smartcard related error message. It happens if you use GnuPG 1.x because it has an older buggier internal CCID implementation, but the one in scdaemon is fine. GnuPG 1.x works too if you use the agent. Try ‘gpg –use-agent’ to make sure it is using the agent.
/Simon
Hi Simon,
thanks for your guide and just being awesome for replying to questions. I managed to generate and import keys onto Yubikey.
The problem was that I didn’t have non root access on the .gnupg/. Changed that, did the Enigmail bugfix found here http://www.amiryan.org/2009/04/22/bugfix-howto-turn-off-gpg-agent-usage-in-enigmail-thunderbird/
and now I can encrypt and decrypt my E-mails using Thunderbird.
Yesterday tried out using the key on a windows pc and managed to use it the first time. After I removed the key and reinserted it, Enigmail says that no key is found. Will reply if I find what the problem was. Probably some weird driver issue.
Pingback: The Case for Short OpenPGP Key Validity Periods | Simon Josefsson's blog
Hi Simon,
Thanks for such a complete write up.
I just got my Yubikey NEO and I do not seem to be able to use it using normal user (under root things seem to work, but I am somewhat disinclined to do it under root).
Are any kind of preparation operations required? Like creating special groups, granting access rights?
OS: Debian/testing.
—
Misha
Hi Mikhail. That sounds strange, everything works for me in normal non-root user mode. What is it that you are tying to do? For GnuPG, make sure that ‘pcsc_scan’ from pcsclite sees the YubiKey NEO. Debug gpg-agent/scdaemon if it doesn’t.
/Simon
I’m trying to use ‘ykinfo -a’ and under root I get the information about the key. Under the non-root user I get permission denied, after checking strace output it turns out that ykinfo tries to access /dev/bus/usb/001/002, which is not available for the user. Same thing happens with ykpersonalize (I believe this is expected).
Another problem (which is not related to permissions) is that while I believe my /etc/libccid_Info.plist has correct information (comes with Debian package libccid 1.4.18-1), pcsc_scan does not really find the key.
Thanks in advance,
—
Misha
Nevermind the pcsc_scan problem: I did not change the mode of the key yet.
I’d appreciate an advice about the other thing though 🙂
—
Misha
I think I solved the problem by modifying /lib/udev/50-udev-default.rules files.
I assume that if I would want to keep all (sub)keys available on my secure machine after saving them with “keytocard” – reducing them to stubs – I should use the pre-export backup keyring? Or is there a way to export the subkeys to the card without deleting them from the GPG keyring?
No matter what machine you have your keys imported to, prior to removal/keytocard you can always export to a file or backup the ~/.gnupg directory to keep a full copy of any [sub]key.
You don’t have to do this process anything like this guy has done it. You can simply generate a new key, the default functions of sign/encrypt are added as subkeys to begin (sometimes only an automatic signing key is created – but usually encryption too for the purpose of encrypting emails, etc) with so you then just add an authentication subkey.
Then, export private key, export subkeys, export public key, to a local directory for safe keeping (move them to a USB stick or to cloud storage, or both). These exported keys are still in your keyring for now.
Now, if you’re created these keys on a disconnected machine (no wifi, no internet) for security reasons, you have no real reason to remove them at all…nothing could ever steal them save another person with access to the machine/account.
So ideally, you’ve already backed up the keys to a USB drive or cloud and are importing the keys into a machine you wish to secure with your yubico. We’ll call this the ‘secure’ machine.
It is this ‘secure’ machine that you keytocard the subkeys on, and remove the master private key from. Why? Well, if the subkeys are still present in full, and not in stubs, then you don’t need the yubico key to authenticate. The idea is to only have the subkeys present in stub form – which tells GPG to defer to a smartcard for the actual key, which ensures that the owner of the smartcard must be present in order to sign/encrypt/authenticate with said private key.
Now, he chose to generate his key on the machine he was securing, then to back them up, then to prep the same machine to be secured by his yubico. Hence -> these instructions are leaving you confused about having access to these keys on your secure machine.
If you want to make your keys on your home machine but not to secure your home machine – but to prep your yubico on your home machine…then the best thing to do is to simply restore your keys from your backup after doing so, which will require that you delete the keys from the keyring first…then you can simply import your keys from the card as stubs on any machine you want to secure with the yubico.
Here’s some debian wiki to show you how to easily prep for securing with subkeys on a machine without all the revocation, etc:
https://wiki.debian.org/Subkeys
Great stuff, thanks very much for the detailed explanations, I managed to work through everything and it works well (got a little stuck around installing the extra packages; and also upon editing the libccid_Info.plist, because I only added the two IDs but not corresponding text string, so the service wouldn’t start, but also give not error message).
Next problem: Make sure other people use the encryption subkey for encryption and not the authentication one. For instance, it seems that Cryptix OpenPGP 0.20050418 (the latest version available and apparently still happily used…) uses my authentication subkey to encrypt messages to me. Which I then cannot decrypt. Any thoughts on that?
Hi Simon,
Why did you choose to let your master key expire, and why so soon? Do you intend to produce another master key in January 2015? Your last master key was good for 12 years.
Devin
For anyone else with the same question, Simon has an answer on his blog:
http://blog.josefsson.org/2014/08/26/the-case-for-short-openpgp-key-validity-periods/
I have two yubikeys, I want one to be a duplicate of the other. I think the way to do this is to generate the three subkeys, backup the private subkeys, copy to the first yubikey (destroying the private subkey in my gpg keyring), then import the private subkeys from the backup and finally copy the subkeys to the second yubikey. Does seem like it will work?
I’m concerned that importing the private subkeys will mess with my keyring, will those private subkeys still be stubs after I import them?
Hi Devin, I’m going to try to do the same thing with my yubikeys – did importing the subkeys from backup and copying them to the second yubikey work for you?
That’s not an efficient way to do that.
You should backup the .gnupg directory prior to your first keytocard onto the first yubico.
Then go ahead and do the process of keytocard’ing the subkeys. Once you’re done, backup the .gnupg directory again.
Your first backup should go to: ../path/to/prior/to/stub
Your second backup should go to: ../path/to/after/stub
At this point restore the original backup. Do the process again to your second Yubico. Done.
If you’re OCD, restore your second backup to legitimately be at the point you were at for the first one.
The other way to do this process is to delete the private master key and public key and all subkeys. Then reimport the original key backup and repeat the process. It’s far simpler to take a backup and restore it for the second key prior to doing your first set of keytocards.
I ran through this guide, and I certainly ran into a lot of stumbling blocks – things like installing the Neo software and getting pcsc-lite + gpg-agent talking to each other that other people have run into. But it worked.
Two comments:
1) I used a LUKS (+ext4) encrypted USB key. There are two advantages to this. First, you won’t run into the issue that FAT drives can’t have Unix domain sockets on them. Second, I got multiple USB keys encrypted this way with copies of the key, and I plan to send them to family/trusted friends as a backup system.
2) I found the point that unless you back up your gpg directory, “keytocard” will *move* the key too subtle, even though you said “destructive”. It’d be nice if gnupg supported “copykeytocard”.
Hm, I just ordered a Yubikey. And I have sort of recently generated keys, but with 4096 bits. Since I was using authentication/signing subkeys, I guess I would have to revoke the whole pair?
I know it is said that you should “never” delete a key pair, but I have never “actually” used it, but I did uploaded it to a key server. Should I revoke the whole old key and create a new one? I am a bit confused about what I could do 🙂
Hi,
Thanks for your howto, I used it and worked with the Neo for some days.
Unfortunately, I had to reset the applet since I inserted the wrong PIN more than three times, and then it is locked. But since i reset the PIN, I can not send the key to the card anymore; according to the error message my key is not supported. Do you have any idea why? I also asked that question (including quotes) on the Yubico-Forum, but no answer yet 🙁
Are you sure you still have the subkeys on your machine? The ‘keytocard’ command only works once, after that the key is gone from the machine. You need to restore the secret subkeys from a backup if you want to re-import it again. I went through this process recently, maybe I should do another blog post describing how to re-import a key to another NEO…
/Simon
I followed the instructions, but ran into a problem with the keytocard command. I get an error. I am using Linux Mint 17.1 with a Gnome-based desktop environment. Any thoughts?
What is the error? Does ‘pcsc_scan’ detect your NEO?
Just wanted to say thanks for the write up! I was able to get it all working on a Mac using the GPGTools application and gpg2 for the card edits. I just wanted to make a note here, in the case that it helps anyone, that I could not use gpg to do the keytocard, I had to use gpg2.
Imagine I followed your steps above and my Yubikey is stolen. Given how Yubikey is done it shouldn’t give anyone else the possibility to use my keys, but I might still want to change the sub-keys stored in it just to be sure.
In this case, I guess I simply generate new sub-keys using my master key, meaning that the master key will sign them. I then use my old sub-key (you did recommend backing it up…) in combination with my new sub-key to generate a transfer certificate.
People has signed my master key as well as old sub-keys, but not my new sub-keys. What trustness level would my new sub-keys have on the key servers? Would any signatures done to master and/or old sub-keys affect this new sub-keys?
Hi Simon,
When doing gpg –edit-key, gpg only modifies the secret key when you actually save the changes. Thus, to avoid having keytocard replace the secret keys with stubs, simple quit the REPL without running save.
Also, gpg 1.4 and gpg 2.0 can’t merge secret keys (this limitation has been removed in gpg 2.1). As such, if you try to reimport your secret keys, it won’t work. Instead, you have to delete the secret key database and then reimport.
Neal
Thanks for the hints Neal. Doing keytocard without save will spare me some frustration in the future.
/Simon
This should definitely be a script. I know it can’t be, and shouldn’t be entirely automated but I know it could be made to be a lot more streamlined for routine key management. The trick I guess would be getting the script onto the offline computer, and I guess the script itself would need to be signed just to cover all of the bases. I guess it could be added to the Live CD/USB, in fact if you can boot from an encrypted (LUKS) USB drive then you could just use it for the OS and the place to store your keys.
Contributions welcome. 🙂
Right now for me I’m still working out the workflow, which has pretty much stabilized. I need one command on the offline machine to update the expiry and export a new key to transfer to the online machine for import. I also need one command on the offline machine to sign other people’s keys. Alas, I have had trouble integrating this with usual tools for PGP signing that sent encrypted emails to people with their key. So far I have uploaded keys that I sign to key servers, which isn’t best practice but usually okay.
/Simon
Hi Simon, at first a grateful thank for this amazing tutorial. After some headache with my yubikey and OpenPGP it now works.
In your last comment you mention a script|command how to update the keys on the key on expiry. It would be awesome, if you could share it with us too.
Thanks again, Dirk
Thanks for this write up! It worked perfectly for me.
Pingback: Yubico Yubikey 4: PGP, U2F and other things | David North
Notes for anybody trying this on Ubuntu 16.04, make sure you enable the “universe” repository if you are running from the LiveCD “Try Ubuntu” state. It isn’t enabled by default, and it is where most of the Yubikey packages are located.
This was incredibly helpful, thanks! One thing I ran into was with Ubuntu 16.04 I had to enable the universe repository. I also was wishing for pcsc-tools to scan for and select a specific smartcard reader since my laptop has one built in as well.
The final hurdle I ran into was a weird error from gpg after uploading a signing key that there was an error on writing the encryption and authentication keys. I was able to get around this by using gpg2 to do the write, but I had to restart the gpg-agent (actually just pulled and reinserted the card) in order to allow gpg2 to access it since gpg1 had a lock on it.
Pingback: Using GnuPG 2.1 and SSH on OS X – Quemarlasnaves
Pingback: Why I don’t Use 2048 or 4096 RSA Key Sizes – Simon Josefsson's blog
Wow,
I surveyed the web and I think this is the best post on the subject! Some tiny questions:
1) What’s the need of the offline machine, I never understood? Any good resource about this?
2) What yubikey version where you using? 4th? If not is the max keysize still 2048 with yubikey 4?
3) How does this relate/consume yubikey slots?
Many thanks for that awesome post.
Thanks! Regarding an offline machine, I consider all online machines potentially compromised through network zero-day exploits. it is just an additional precaution.
I am using the YubiKey NEO. The YubiKey 4 supports 4k RSA keys.
If you are thinking about YubiKey OTP slots, this is completely unrelated. The OpenPGP part of the YubiKey is separate from the OTP part. OpenPGP Cards have room for three keys, this is per the standard.
Hope this helps!
/Simon
Yes it does, thanks again!
Pingback: How I setup my new 2016 MacBook Pro | The Man in the Arena
Pingback: PGP – Première exploration – Unicoda
Pingback: GnuPG, clefs, YubiKey : c’est parti – Unicoda
Pingback: Planning for a new OpenPGP key – Simon Josefsson's blog
Pingback: OpenPGP Smartcards and GNOME – Simon Josefsson's blog
Pingback: Getting Started With A Crypto Stick (Nitrokey Start) – My Way With Java
Pingback: How I setup my 2021 MacBook Pro | The Man in the Arena
Pingback: OpenPGP key on FST-01SZ – Simon Josefsson's blog
Pingback: Andrea Grandi – Configuring an offline GnuPG master key and subkeys on YubiKey
Pingback: Offline Ed25519 OpenPGP key with subkeys on FST-01G running Gnuk – Simon Josefsson's blog
Pingback: OpenPGP master key on Nitrokey Start – Simon Josefsson's blog