GnuPG
Those are personal notes when I decided in 2016 to generate a new key as transition from my previous one (from 2002!).
Daily subkeys are stored on a Yubikey NEO-n and master key is stored offline.
Resources
The steps I followed and which I describe only very briefly here, more to remind how I combined them, came from those excellent resources:
- https://help.riseup.net/en/security/message-security/openpgp/best-practices
- http://ekaia.org/blog/2009/05/10/creating-new-gpgkey/
- https://www.esev.com/blog/post/2015-01-pgp-ssh-key-on-yubikey-neo/
gpg.conf
First step was to refresh a little bit my gpg.conf.
See https://github.com/ioerror/duraconf/raw/master/configs/gnupg/gpg.conf for commented gpg.conf and https://help.riseup.net/en/security/message-security/openpgp/best-practices for the reasons behind.
no-emit-version no-comments keyid-format 0xlong with-fingerprint list-options show-uid-validity verify-options show-uid-validity use-agent keyserver hkps://hkps.pool.sks-keyservers.net keyserver-options ca-cert-file=/home/phil/.gnupg/keyservers/sks-keyservers.netCA.pem keyserver-options no-try-dns-srv keyserver-options no-honor-keyserver-url keyserver-options include-revoked personal-cipher-preferences AES256 AES192 AES CAST5 personal-digest-preferences SHA512 SHA384 SHA256 SHA224 cert-digest-algo SHA512 default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
Some more of my own:
no-greeting keyserver-options auto-key-retrieve honor-http-proxy list-options show-policy-urls show-notations show-keyserver-urls show-uid-validity show-unusable-uids show-unusable-subkeys show-sig-expire verify-options show-photos show-policy-urls show-notations show-keyserver-urls show-uid-validity show-unusable-uids utf8-strings ask-cert-level
Offline storage
Digressing a little bit...
I chose an old SDCard to store the master key offline, but it required a little bit of maintenance because it wasn't mounting automatically:
Making sude partition table was ok:
$ sudo fdisk /dev/mmcblk0
Checking FS signatures:
$ sudo wipefs /dev/mmcblk0p1
There was still a mix of FAT and ext2 signatures, so deleting the ext2 signature based on the returned offset:
$ sudo wipefs -o 0x438 /dev/mmcblk0p1
Formatting
$ sudo mkfs.vfat /dev/mmcblk0p1 $ sudo fatlabel /dev/mmcblk0p1 GNUPG
Reinserting it to get it mounted automatically, then
$ cp ~/.gnupg/gpg.conf /media/phil/GNUPG $ sudo mount --bind /media/phil/GNUPG ~/.gnupg
Entropy
Creating large keys require large entropy.
I like haveged for that:
$ sudo apt-get install haveged
Creating main key
Idea following https://www.esev.com/blog/post/2015-01-pgp-ssh-key-on-yubikey-neo/ is to keep the main key completely offline so if yubikey is lost, there is still some hope.
$ gpg --expert --gen-key Please select what kind of key you want: (8) RSA (set your own capabilities) Your selection? 8 Current allowed actions: Sign Certify Encrypt Your selection? s Your selection? e Current allowed actions: Certify Your selection? q What keysize do you want? (2048) 4096 Requested keysize is 4096 bits Key is valid for? (0) 2y Is this correct? (y/N) y Real name: Philippe Teuwen Email address: phil@teuwen.org Comment: You selected this USER-ID: "Philippe Teuwen <phil@teuwen.org>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o gpg: key 0x9B554C36544C89BC marked as ultimately trusted public and secret key created and signed.
Creating revokation certificate
$ gpg --gen-revoke 9B554C36544C89BC > /media/phil/GNUPG/rev-phil_teuwen.org_2016 sec 4096R/0x9B554C36544C89BC 2016-02-04 Philippe Teuwen <phil@teuwen.org> Create a revocation certificate for this key? (y/N) y Please select the reason for the revocation: 3 = Key is no longer used Your decision? 3 Enter an optional description; end it with an empty line: >Using revocation certificate that was generated when key was created. >It is very likely that I have lost access to the private key. > Reason for revocation: Key is no longer used Using revocation certificate that was generated when key was created. It is very likely that I have lost access to the private key. Is this okay? (y/N) y
Then printing it on paper
Creating Encryption subkey
Idea following https://www.esev.com/blog/post/2015-01-pgp-ssh-key-on-yubikey-neo/ is to create the encryption key out of yubikey and importing it so it can be imported on several yubikey's.
$ gpg --edit-key 9B554C36544C89BC gpg> addkey Please select what kind of key you want: (6) RSA (encrypt only) Your selection? 6 What keysize do you want? (2048) 2048 Please specify how long the key should be valid. Key is valid for? (0) 2y Is this correct? (y/N) y Really create? (y/N) y pub 4096R/0x9B554C36544C89BC created: 2016-02-04 expires: 2018-02-03 usage: C trust: ultimate validity: ultimate sub 2048R/0x47B68B62B62C8F88 created: 2016-02-04 expires: 2018-02-03 usage: E [ultimate] (1). Philippe Teuwen <phil@teuwen.org> gpg> save
Backup the secret key
The "keytocard / save" operations that we will do later will also remove the secret key from your keyring, so better to backup it first!
$ gpg --export-secret-key 9B554C36544C89BC > /media/phil/GNUPG/9B554C36544C89BC-2016-02-04-47B68B62B62C8F88-secret.pgp $ gpg --delete-secret-key 9B554C36544C89BC $ gpg --import < /media/phil/GNUPG/9B554C36544C89BC-2016-02-04-47B68B62B62C8F88-secret.pgp
Yubikey
$ sudo apt-get install yubikey-personalization ykneomgr $ wget https://raw.githubusercontent.com/Yubico/yubikey-personalization/master/69-yubikey.rules $ wget https://raw.githubusercontent.com/Yubico/yubikey-personalization/master/70-yubikey.rules $ sudo mv *rules /etc/udev/rules.d/ $ sudo chown root.root /etc/udev/rules.d/*yubikey.rules
Insert yubikey NEO-n
$ ykinfo -a
On a Yubikey where HID has been deactivated, ykinfo will fail, use ykneomgr instead.
If ykneomgr fails, it may be because you used it for gpg via scdaemon.
Even with "card-timeout 1" in .gnupg/scdaemon.conf I experienced problems once I read some encrypted emails, I have to restart pcscd to free the Yubikey and be able to use ykneomgr.
To keep possibility to use all modes simultaneously:
$ ykpersonalize -m86 Firmware version 3.3.0 Touch level 1285 Program sequence 1 The USB mode will be set to: 0x86 Commit? (y/n) [n]: y
If ykpersonalize doesn't work (no HID), see ykneomgr
I wanted to disable HID (as I don't use it but still touch accidentally the key now and then).
But switching to mode 5 (U2F+CCID) didn't disable HID so to get it working I had to switch to mode 1 (CCID) then 5 (U2F+CCID):
ykneomgr -M1 ykneomgr -M5
Creating Signature and Authentication subkeys
Yes default admin PIN is 12345678 and default user PIN is 123456.
We'll change them later.
$ gpg --edit-key 9B554C36544C89BC gpg> addcardkey Please select the type of key to generate: (1) Signature key Your selection? 1 Enter Admin PIN: 12345678 Enter PIN: 123456 Please specify how long the key should be valid. Key is valid for? (0) 2y Is this correct? (y/N) y Really create? (y/N) y pub 4096R/0x9B554C36544C89BC created: 2016-02-04 expires: 2018-02-03 usage: C trust: ultimate validity: ultimate sub 2048R/0x47B68B62B62C8F88 created: 2016-02-04 expires: 2018-02-03 usage: E sub 2048R/0xAEBAADBEE208E2DD created: 2016-02-04 expires: 2018-02-03 usage: S [ultimate] (1). Philippe Teuwen <phil@teuwen.org>
gpg> addcardkey Please select the type of key to generate: (3) Authentication key Your selection? 3 Please specify how long the key should be valid. Key is valid for? (0) 2y Is this correct? (y/N) y Really create? (y/N) y pub 4096R/0x9B554C36544C89BC created: 2016-02-04 expires: 2018-02-03 usage: C trust: ultimate validity: ultimate sub 2048R/0x47B68B62B62C8F88 created: 2016-02-04 expires: 2018-02-03 usage: E sub 2048R/0xAEBAADBEE208E2DD created: 2016-02-04 expires: 2018-02-03 usage: S sub 2048R/0xE5151B7FDCA95A14 created: 2016-02-04 expires: 2018-02-03 usage: A [ultimate] (1). Philippe Teuwen <phil@teuwen.org>
Ready to import Encryption subkey?
At this point we should import the encryption key to the yubikey but I got some error:
gpg: error writing key to card: not supported
Some say to use keyParser.py but I found out gpg2 works. Gpg could work directly with the card (except for the keytocard obviously) but Gpg2 needs sdaemon for that:
$ sudo apt-get install gnupg2 scdaemon
Yet another quirk: gnupg gave some warnings about locking from FAT but gnupg2 just refuses using FAT, so I add to the gpg.conf of the SD-Card:
# allow linux to write to FAT disks lock-never
While this was working fine earlier, at some point I experiended:
$ gpg2 --card-status gpg: OpenPGP card not available: Not supported
The fix was to forbid scdaemon to use the CCID driver but to use PCSC instead. Edit .gnupg/scdaemon.conf:
card-timeout 1 disable-ccid
The "card-timeout" is supposed to free the card when not in use, still I've typically to restart pcscd if scdaemon keeps locking it.
Encryption key to Yubikey
$ gpg2 --edit-key 9B554C36544C89BC gpg> toggle gpg> key 1 sec 4096R/0x9B554C36544C89BC created: 2016-02-04 expires: 2018-02-03 ssb* 2048R/0x47B68B62B62C8F88 created: 2016-02-04 expires: never ssb 2048R/0xAEBAADBEE208E2DD created: 2016-02-04 expires: never card-no: 0006 03037217 ssb 2048R/0xE5151B7FDCA95A14 created: 2016-02-04 expires: never card-no: 0006 03037217 (1) Philippe Teuwen <phil@teuwen.org> gpg> keytocard Please select where to store the key: (2) Encryption key Your selection? 2 gpg> save
Adding UID and photo
Choose a 240x288 picture strongly compressed (I chose jpeg quality 20) to obtain a size < 5kb.
$ gpg2 --edit-key 9B554C36544C89BC gpg> adduid Real name: Philippe Teuwen Email address: pteuwen@quarkslab.com Comment: You selected this USER-ID: "Philippe Teuwen <pteuwen@quarkslab.com>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o gpg> addphoto Enter JPEG filename for photo ID: ~/phil20.jpg pub 4096R/0x9B554C36544C89BC created: 2016-02-04 expires: 2018-02-03 usage: C trust: ultimate validity: ultimate sub 2048R/0x47B68B62B62C8F88 created: 2016-02-04 expires: 2018-02-03 usage: E sub 2048R/0xAEBAADBEE208E2DD created: 2016-02-04 expires: 2018-02-03 usage: S sub 2048R/0xE5151B7FDCA95A14 created: 2016-02-04 expires: 2018-02-03 usage: A [ultimate] (1) Philippe Teuwen <phil@teuwen.org> [ unknown] (2). Philippe Teuwen <pteuwen@quarkslab.com> [ unknown] (3) [jpeg image of size 4266] gpg> uid 1 gpg> primary gpg> save
Almost there
Exporting key
$ gpg --armor --export 9B554C36544C89BC > /media/phil/GNUPG/9B554C36544C89BC.asc
And pushing it to http://www.yobi.be/files/9B554C36544C89BC.asc
Back to the daily .gnupg
$ sudo umount ~/.gnupg
Changing default PINs
$ gpg --card-edit gpg/card> admin Admin commands are allowed gpg/card> passwd gpg: OpenPGP card no. D2760001240102000006030372170000 detected 1 - change PIN Your selection? 1 Please enter the PIN 123456 New PIN ... New PIN ... PIN changed. 3 - change Admin PIN Your selection? 3 gpg: 3 Admin PIN attempts remaining before card is permanently locked Please enter the Admin PIN 12345678 New Admin PIN ... New Admin PIN ... PIN changed. Q - quit Your selection? q gpg/card> forcesig gpg/card> url URL to retrieve public key: http://www.yobi.be/files/9B554C36544C89BC.asc gpg/card> fetch gpg: requesting key 0xAEBAADBEE208E2DD from http server www.yobi.be gpg/card> quit
$ gpg --card-status Application ID ...: D2760001240102000006030372170000 Version ..........: 2.0 Manufacturer .....: unknown Serial number ....: xxxxxxxxx Name of cardholder: [not set] Language prefs ...: [not set] Sex ..............: unspecified URL of public key : http://www.yobi.be/files/9B554C36544C89BC.asc Login data .......: [not set] Signature PIN ....: not forced Key attributes ...: 2048R 2048R 2048R Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 3 Signature counter : 2 Signature key ....: 67E1 AAA2 46D7 9037 7671 BAD5 AEBA ADBE E208 E2DD created ....: 2016-02-04 10:56:03 Encryption key....: 55A5 1FF1 F45A A846 EC12 A5D4 47B6 8B62 B62C 8F88 created ....: 2016-02-04 10:26:52 Authentication key: 93FE E3BA 0F4D 4461 19E8 1CBE E515 1B7F DCA9 5A14 created ....: 2016-02-04 10:57:35 General key info..: pub 2048R/0xAEBAADBEE208E2DD 2016-02-04 Philippe Teuwen <phil@teuwen.org> sec# 4096R/0x9B554C36544C89BC created: 2016-02-04 expires: 2018-02-03 ssb> 2048R/0x47B68B62B62C8F88 created: 2016-02-04 expires: 2018-02-03 card-no: 0006 03037217 ssb> 2048R/0xAEBAADBEE208E2DD created: 2016-02-04 expires: 2018-02-03 card-no: 0006 03037217 ssb> 2048R/0xE5151B7FDCA95A14 created: 2016-02-04 expires: 2018-02-03 card-no: 0006 03037217
Changing default key in gpg.conf
default-key 0xF14883379E8DD09F03280E1B9B554C36544C89BC
Last check
$ sudo apt-get install hopenpgp-tools $ hkt export-pubkeys 'AEBAADBEE208E2DD' | hokey lint
All green \o/
Using Yubikey on another machine
$ gpg --card-edit gpg/card> fetch
Signing new key with the old one
$ gpg --default-key 9ad7e3db --sign-key 9B554C36544C89BC Really sign all user IDs? (y/N) y (3) I have done very careful checking. Your selection? (enter `?' for more information): 3 Really sign? (y/N) y
$ gpg --send-key 9B554C36544C89BC
As it's a pool I sent it 10x, rather than waiting them to all sync...
And also for those still using pgp.mit.edu:
$ gpg --keyserver pgp.mit.edu --send-key 9B554C36544C89BC
Transition
Now let's ask some helpful souls who signed my old key.
Stealing and adapting key transition text from https://we.riseup.net/assets/176898/key%20transition
Mass mailing to those who've signed the old one:
$ gpg --list-sigs 9ad7e3db|grep ^sig|sed 's/.*<//;s/>.*//;/^sig/d'|sort|uniq|tr '\n' ','
Date: 2016-02-04 For a number of reasons[0], I've recently set up a new OpenPGP key, and will be transitioning away from my old one. The old key will continue to be valid for some time, but I prefer all future correspondence to come to the new one. I would also like this new key to be re-integrated into the web of trust. This message is signed by both keys to certify the transition. The old key was: pub 1024D/0x7A135F579AD7E3DB 2002-05-05 [expires: 2017-08-13] sub 2048g/0x78FC60279A4A59B9 2002-05-05 [expires: 2017-08-13] sub 4096R/0xF2FD1762608F63B7 2007-08-16 [expires: 2017-08-13] fingerprint = 440A 3A9E 56E9 D90E 99D7 63A8 7A13 5F57 9AD7 E3DB And the new key is: pub 4096R/0x9B554C36544C89BC 2016-02-04 [expires: 2018-02-03] sub 2048R/0x47B68B62B62C8F88 2016-02-04 [expires: 2018-02-03] sub 2048R/0xAEBAADBEE208E2DD 2016-02-04 [expires: 2018-02-03] sub 2048R/0xE5151B7FDCA95A14 2016-02-04 [expires: 2018-02-03] fingerprint = F148 8337 9E8D D09F 0328 0E1B 9B55 4C36 544C 89BC To fetch the full key from a public key server, you can simply do: gpg --keyserver pool.sks-keyservers.net --recv-key F14883379E8DD09F03280E1B9B554C36544C89BC If you already know my old key, you can now verify that the new key is signed by the old one: gpg --check-sigs F14883379E8DD09F03280E1B9B554C36544C89BC If you don't already know my old key, or you just want to be double extra paranoid, you can check the fingerprint against the one above: gpg --fingerprint F14883379E8DD09F03280E1B9B554C36544C89BC If you are satisfied that you've got the right key, and the UIDs match what you expect, I'd appreciate it if you would sign my key. You can do that by issuing the following command: ** NOTE: if you have previously signed my key but did a local-only signature (lsign), you will not want to issue the following, instead you will want to use --lsign-key, and not send the signatures to the keyserver ** gpg --sign-key F14883379E8DD09F03280E1B9B554C36544C89BC I'd like to receive your signatures on my key. You can either send me an e-mail with the new signatures (if you have a functional MTA on your system): gpg --export F14883379E8DD09F03280E1B9B554C36544C89BC | \ gpg --encrypt -r F14883379E8DD09F03280E1B9B554C36544C89BC --armor | \ mail -s 'OpenPGP Signatures' phil@teuwen.org Additionally, I highly recommend that you implement a mechanism to keep your key material up-to-date so that you obtain the latest revocations, and other updates in a timely manner. You can do regular key updates by using parcimonie[1] to refresh your keyring. Parcimonie is a daemon that slowly refreshes your keyring from a keyserver over Tor. It uses a randomized sleep, and fresh tor circuits for each key. The purpose is to make it hard for an attacker to correlate the key updates with your keyring. I also highly recommend checking out the excellent Riseup GPG best practices doc, from which I stole most of the text for this transition message ;-) https://we.riseup.net/debian/openpgp-best-practices Please let me know if you have any questions, or problems, and sorry for the inconvenience. If you're curious, I've briefly documented all the steps using a Yubikey on my wiki [2]. Philippe Teuwen 0. https://www.debian-administration.org/users/dkg/weblog/48 1. https://gaffer.ptitcanardnoir.org/intrigeri/code/parcimonie/ 2. http://wiki.yobi.be/wiki/GnuPG
In an email signed with my old key...
Signing keys
To sign keys it requires the SD-Card.
To enable it:
cp -a ~/.gnupg/pubring.gpg /media/phil/GNUPG/ cp -a ~/.gnupg/trustdb.gpg /media/phil/GNUPG/ sudo mount --bind /media/phil/GNUPG ~/.gnupg
To disable it:
sudo umount ~/.gnupg cp -a /media/phil/GNUPG/pubring.gpg ~/.gnupg/ cp -a /media/phil/GNUPG/trustdb.gpg ~/.gnupg/
Extending expiration time
sudo service pcscd stop cp -a ~/.gnupg/pubring.gpg /media/phil/GNUPG/ cp -a ~/.gnupg/trustdb.gpg /media/phil/GNUPG/ sudo mount --bind /media/phil/GNUPG ~/.gnupg gpg --edit-key 9B554C36544C89BC key 47B68B62B62C8F88 key C68777A356ACFA91 key C83BE1071CDE1015 expire 3y save sudo umount ~/.gnupg cp -a /media/phil/GNUPG/pubring.gpg ~/.gnupg/ cp -a /media/phil/GNUPG/trustdb.gpg ~/.gnupg/ gpg --armor --export 9B554C36544C89BC > /media/phil/GNUPG/9B554C36544C89BC.asc umount /media/phil/GNUPG sudo service pcscd start gpg --keyserver keys.gnupg.net --send-key 9B554C36544C89BC gpg --armor --export 9B554C36544C89BC > /tmp/9B554C36544C89BC.asc
And pushing it to http://www.yobi.be/files/9B554C36544C89BC.asc
OpenSSH
Using the OpenPGP key and the Yubikey for OpenSSH
$ sudo apt-get install monkeysphere
We need to specifying the authentication subkey here!
$ gpgkey2ssh E5151B7FDCA95A14 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCeNXjx+2M1F7CuYRMkoHv6iUnXe93JatAjhmh1ciXIrTk/Agc4JEgb9uTxYA3pNe/qXVSrSdAqJu0cUENj30rLvKOliL0MH1TxGDnZ0JSxv0UA/skwapRwiTKgsHHng7gbq1/07eBl0luywLT1E/4sbeZ6cAK9e8JAO9GahiyYnrzt2nXzoVxGYl2AHkHFuCqHEMH/KQuQ8Tba+ZjqpRbjnreuI9tJQ8eWpMjLr2AYuWgAU5GtbWFHJi0WJI/2kYybT7co7Kldoxg8PRvBE/QQPdP811jc06pf4CVgfCGvCWZaslqG5pLy8LneqYciuQuXDCQMlAWniThTPjf5VLhx COMMENT
Paper backup of the secret keys
If you don't trust SD-Card longevity...
apt-get install paperkey gpg --export-secret-key key_id | paperkey
OpenPGP cards
See https://en.wikipedia.org/wiki/OpenPGP_card for existing cards.
OpenPGP card 3.x JavaCard Applets
- SmartPGP, an implementation of the OpenPGP card 3.x specification in JavaCard (>=3.0.4) by ANSSI, including elliptic curves and RSA-4096
sudo apt-get install ant
git clone git@github.com:martinpaljak/oracle_javacard_sdks.git
git clone git@github.com:ANSSI-FR/SmartPGP.git
cd SmartPGP
echo JAVACARD_HOME=$(pwd)/../oracle_javacard_sdks/jc304_kit > javacard.properties
ant
# => ./build/fr/anssi/smartpgp/javacard/smartpgp.cap
This requires a JavaCard 3.0.4 compliant card but it might be used with JavaCard 3.0.1 cards without the ECC parts, see this issue and the javacard-3.0.1 branch.
OpenPGP card 2.x JavaCard Applets
See also https://subgraph.com/sgos/documentation/smartcards/index.fr.html
Yubikey and FluffyKaon implementations can be easily compiled from https://github.com/martinpaljak/AppletPlayground:
git clone https://github.com/martinpaljak/AppletPlayground.git
cd AppletPlayground
ant
The author has also a GlobalPlatform tool to inject the CAP into the card.
To compile it you need openjdk-7-jdk which at the moment seems hard to get on my Debian (old dependencies problem), so I'll stick to openjdk-8 and fetch a pre-built version here.
Usage:
java -jar gp.jar --help
Or using JCOP's jcshell:
/card auth upload OpenPGPApplet.cap install D27600012401 D2760001240102000000000000010000 ctrl^d
Testing the newly created OpenPGP card:
gpg --card-status
Adding an OpenPGP card
How to add a card (YubiKey or JavaCard) to an existing key, using our backup SDCard.
First check that the card is accessible:
$ gpg --card-status Reader ...........: Yubico Yubikey 4 OTP U2F CCID 00 00 Application ID ...: D2760001240102010006069331940000 Version ..........: 2.1 Manufacturer .....: Yubico Serial number ....: 06933194 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]
You may have problems getting it detected, especially if another card was used before. Reboot.
Map the SDCard:
$ pkill gpg-agent
# mount --bind /media/phil/GNUPG ~/.gnupg
Import again the keys (mainly the encryption key) moved to previous cards:
$ gpg --import < ~/.gnupg/9B554C36544C89BC-2016-02-04-47B68B62B62C8F88-secret.pgp
Create new sub-keys:
$ gpg --edit-key 9B554C36544C89BC
gpg> addcardkey
Please select the type of key to generate:
(1) Signature key
# remember default PIN is 123456, default admin PIN is 12345678
What keysize do you want for the Signature key? (2048) 4096
Key is valid for? (0) 2y
Is this correct? (y/N) y
Really create? (y/N) y
# wait for key to be generated and provide PINs if requested
gpg> addcardkey
Please select the type of key to generate:
(3) Authentication key
What keysize do you want for the Authentication key? (2048) 4096
Key is valid for? (0) 2y
Is this correct? (y/N) y
Really create? (y/N) y
gpg> save
Btw the notation "sec#" or "ssb#" means the key or subkey is not accessible (it's on another keyring or card).
The notation "sec>" or "ssb>" means the card or subcard is stored on a card known to the system.
The same convention is used with gpg --list-secret-keys
Now we can try to transfer the encryption key but it will probably fail because it's still associated with the previous card:
$ gpg2 --edit-key 9B554C36544C89BC
ssb rsa2048/0x47B68B62B62C8F88
created: 2016-02-04 expires: 2018-02-03 usage: E
card-no: 0000 00000001 <= still previous card
gpg> toggle
gpg> key 1
ssb* rsa2048/0x47B68B62B62C8F88
created: 2016-02-04 expires: 2018-02-03 usage: E
card-no: 0000 00000001 <= still previous card
gpg> keytocard
Please select where to store the key:
(2) Encryption key
Your selection? 2
gpg: KEYTOCARD failed: Unusable secret key
The only solution I found was to clean the secret keyring, import again and sync card again:
$ pkill gpg-agent
$ mv .gnupg/private-keys-v1.d/ .gnupg/private-keys-v1.d.old
$ gpg --import < ~/.gnupg/9B554C36544C89BC-2016-02-04-47B68B62B62C8F88-secret.pgp
$ gpg --card-status
$ gpg2 --edit-key 9B554C36544C89BC
Secret key is available.
sec rsa4096/0x9B554C36544C89BC
created: 2016-02-04 expires: 2018-02-03 usage: C
trust: ultimate validity: ultimate
ssb rsa2048/0x47B68B62B62C8F88
created: 2016-02-04 expires: 2018-02-03 usage: E
sub rsa2048/0xAEBAADBEE208E2DD
created: 2016-02-04 expires: 2018-02-03 usage: S
sub rsa2048/0xE5151B7FDCA95A14
created: 2016-02-04 expires: 2018-02-03 usage: A
sub rsa2048/0xF7B61B5663205C74
created: 2017-12-02 expires: 2019-12-02 usage: S
sub rsa2048/0xBDBF13DADE186465
created: 2017-12-02 expires: 2019-12-02 usage: A
ssb rsa4096/0xC68777A356ACFA91
created: 2017-12-07 expires: 2019-12-07 usage: S
card-no: 0006 06933194
ssb rsa4096/0xC83BE1071CDE1015
created: 2017-12-07 expires: 2019-12-07 usage: A
card-no: 0006 06933194
We see the encryption is not bound to a card anymore and the two new subkeys are bound to our card. So we can try again:
$ gpg2 --edit-key 9B554C36544C89BC
ssb rsa2048/0x47B68B62B62C8F88
created: 2016-02-04 expires: 2018-02-03 usage: E
gpg> toggle
gpg> key 1
ssb* rsa2048/0x47B68B62B62C8F88
created: 2016-02-04 expires: 2018-02-03 usage: E
gpg> keytocard
Please select where to store the key:
(2) Encryption key
Your selection? 2
gpg> save
Export the public key and unmount the SDCard:
$ gpg --armor --export 9B554C36544C89BC > ~/.gnupg/9B554C36544C89BC_v3.asc
$ pkill gpg-agent
$ sudo umount ~/.gnupg
$ gpg --import < /media/phil/GNUPG/9B554C36544C89BC_v3.asc
$ gpg --card-status
$ gpg --edit-key 9B554C36544C89BC
The encryption key is probably still linked to the previous card.
Again, I didn't see a clean way to do it.
Backup your secret keyring before messing up with it, then, try to find the file corresponding to the encryption key.
It's a file smaller than the others, containing a string "shadowed-private-key". Compare it with the other gnupg secret keyring: /media/phil/GNUPG/private-keys-v1.d/ and replace it with the new copy (or just delete it, it should be synced again from the card).
cp /media/phil/GNUPG/private-keys-v1.d/AFE2DF0A021D08C752DE0ED0A8D020E8E57F4296.key ~/.gnupg/private-keys-v1.d
Now edit the key again, the encryption subkey should be associated with the new card.
Edit the card for the final adjustments:
$ gpg --card-edit gpg/card> admin gpg/card> passwd 1 - change PIN Your selection? 1 PIN changed. 3 - change Admin PIN Your selection? 3 PIN changed. Your selection? q gpg/card> forcesig gpg/card> name Cardholder's surname: Teuwen Cardholder's given name: Philippe gpg/card> url URL to retrieve public key: http://www.yobi.be/files/9B554C36544C89BC.asc gpg/card> fetch gpg: requesting key from 'http://www.yobi.be/files/9B554C36544C89BC.asc' gpg/card> quit
Push the updated key to various keyservers.
gpg --keyserver hkps.pool.sks-keyservers.net --send-key 9B554C36544C89BC