Difference between revisions of "GnuPG"
m |
|||
(55 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | Those are personal notes when I decided in 2016 to generate a new key as transition from my previous one (from 2002!). |
||
− | ''French part was converted with [[MediaWiki#HTML-WikiConverter|HTML::WikiConverter::MediaWiki]] from my old phpwiki site'' |
||
+ | <br>Daily subkeys are stored on a Yubikey NEO-n and master key is stored offline. |
||
− | ==Intro== |
||
− | Un très bon point de départ: http://www.gnupg.org/gph/fr/manual.html |
||
+ | ==Resources== |
||
− | Une introduction a GnuPG(vulgaristation): http://www.vilya.org/gpg/ |
||
+ | 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. |
||
+ | <br>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. |
||
+ | <pre> |
||
+ | 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 |
||
+ | </pre> |
||
+ | Some more of my own: |
||
+ | <pre> |
||
+ | 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 |
||
+ | </pre> |
||
+ | ==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: |
||
− | On peut les trouver un peu partout. |
||
+ | Making sude partition table was ok: |
||
− | gpg --keyserver wwwkeys.pgp.net --recv-key 0x7A135F579AD7E3DB |
||
+ | $ 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. |
||
+ | <br>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 |
||
− | == Serveurs publics == |
||
+ | 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! |
||
− | * http://wwwkeys.pgp.net |
||
− | * [http://sks-keyservers.net/status/ A list...] |
||
− | * http://pgp.mit.edu (very slow) |
||
+ | $ gpg --export-secret-key 9B554C36544C89BC > /media/phil/GNUPG/9B554C36544C89BC-2016-02-04-47B68B62B62C8F88-secret.pgp |
||
− | == Key Signing Coordination == |
||
+ | $ gpg --delete-secret-key 9B554C36544C89BC |
||
+ | $ gpg --import < /media/phil/GNUPG/9B554C36544C89BC-2016-02-04-47B68B62B62C8F88-secret.pgp |
||
+ | ==Yubikey== |
||
− | http://www.biglumber.com/ |
||
+ | $ 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. |
||
+ | <br>If ykneomgr fails, it may be because you used it for gpg via scdaemon. |
||
+ | <br>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: |
||
− | == Distance entre clés == |
||
+ | $ 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). |
||
− | Par exemple<br />[http://keyserver.kjsl.com/~jharris/gpgwww.cgi?from=135EA668&to=9AD7E3DB http://keyserver.kjsl.com/~jharris/gpgwww.cgi?from=135EA668&to=9AD7E3DB]<br />[http://keyserver.kjsl.com/~jharris/gpgwww.cgi?from=449FA3AB&to=9AD7E3DB http://keyserver.kjsl.com/~jharris/gpgwww.cgi?from=449FA3AB&to=9AD7E3DB]<br />Remplacer les IDs des clés pour essayer d'autres chemins. |
||
+ | <br>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== |
||
− | Update: les URLs précédentes ne fonctionnent apparemment plus, vous pouvez essayer avec celles-ci:<br> |
||
+ | Yes default admin PIN is 12345678 and default user PIN is 123456. |
||
− | http://pgp.cs.uu.nl/mk_path.cgi?FROM=135EA668&TO=9AD7E3DB&PATHS=trust+paths<br> |
||
+ | <br>We'll change them later. |
||
− | http://pgp.cs.uu.nl/mk_path.cgi?FROM=449FA3AB=9AD7E3DB&PATHS=trust+paths |
||
+ | $ 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 |
||
− | [http://www.cs.uu.nl/people/henkp/henkp/pgp/pathfinder/mk_path.cgi?STAT=9AD7E3DB&STATS=statistics http://www.cs.uu.nl/people/henkp/henkp/pgp/pathfinder/mk_path.cgi?STAT=9AD7E3DB&STATS=statistics] |
||
+ | 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 [https://github.com/Yubico/ykneo-openpgp/tree/master/util 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: |
||
− | === Strong Set === |
||
+ | $ 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: |
||
− | Une analyse mensuelle est disponible ici: http://dtype.org/keyanalyze/<br />[http://www.dtype.org/keyanalyze/output/200208/9A/9AD7E3DB J'y suis rentré en août 2002] avec une distance moyenne de 6.9916 (merci adulau ;-) <br />Des analyses plus récentes sont disponibles ici: http://keyserver.kjsl.com/~jharris/ka |
||
+ | 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. |
||
− | <div class="plugin tightenable top"> |
||
+ | ==Encryption key to Yubikey== |
||
− | {| border="1" cellspacing="1" cellpadding="1" |
||
+ | $ gpg2 --edit-key 9B554C36544C89BC |
||
− | | align="left" | strong>Date</strong> |
||
+ | gpg> toggle |
||
− | | align="left" | strong>Mean dist</strong> |
||
+ | gpg> key 1 |
||
− | | align="left" | strong>World class</strong> |
||
+ | sec 4096R/0x9B554C36544C89BC created: 2016-02-04 expires: 2018-02-03 |
||
− | | align="left" | strong>From Set to ID</strong> |
||
+ | ssb* 2048R/0x47B68B62B62C8F88 created: 2016-02-04 expires: never |
||
− | | align="left" | strong>From ID to Set</strong> |
||
+ | ssb 2048R/0xAEBAADBEE208E2DD created: 2016-02-04 expires: never |
||
− | | align="left" | strong>Max hops</strong> |
||
+ | card-no: 0006 03037217 |
||
− | | align="left" | strong>Strong set</strong> |
||
+ | ssb 2048R/0xE5151B7FDCA95A14 created: 2016-02-04 expires: never |
||
− | | align="left" | strong>Average mean</strong> |
||
+ | card-no: 0006 03037217 |
||
− | |- |
||
+ | (1) Philippe Teuwen <phil@teuwen.org> |
||
− | | align="left" | |
||
+ | gpg> keytocard |
||
− | [http://www.dtype.org/keyanalyze/output/200208/ 08-2002] |
||
+ | Please select where to store the key: |
||
− | | align="left" | 6.9916 |
||
+ | (2) Encryption key |
||
− | | align="left" | >1000 |
||
+ | Your selection? 2 |
||
− | | align="left" | - |
||
+ | gpg> save |
||
− | | align="left" | - |
||
+ | ==Adding UID and photo== |
||
− | | align="left" | 15 |
||
+ | Choose a 240x288 picture strongly compressed (I chose jpeg quality 20) to obtain a size < 5kb. |
||
− | | align="left" | 14159 |
||
+ | $ gpg2 --edit-key 9B554C36544C89BC |
||
− | | align="left" | 6.5105 |
||
+ | gpg> adduid |
||
− | |- |
||
+ | Real name: Philippe Teuwen |
||
− | | align="left" | |
||
+ | Email address: pteuwen@quarkslab.com |
||
− | [http://skylane.kjsl.com/~jharris/ka/2002-08-11/ 11-08-2002] |
||
+ | Comment: |
||
− | | align="left" | 5.7041 |
||
+ | You selected this USER-ID: |
||
− | | align="left" | >1000 |
||
+ | "Philippe Teuwen <pteuwen@quarkslab.com>" |
||
− | | align="left" | - |
||
+ | Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o |
||
− | | align="left" | - |
||
+ | |||
− | | align="left" | 14 |
||
+ | gpg> addphoto |
||
− | | align="left" | 14353 |
||
+ | Enter JPEG filename for photo ID: ~/phil20.jpg |
||
− | | align="left" | 6.5222 |
||
+ | pub 4096R/0x9B554C36544C89BC created: 2016-02-04 expires: 2018-02-03 usage: C |
||
− | |- |
||
+ | trust: ultimate validity: ultimate |
||
− | | align="left" | |
||
+ | sub 2048R/0x47B68B62B62C8F88 created: 2016-02-04 expires: 2018-02-03 usage: E |
||
− | [http://skylane.kjsl.com/~jharris/ka/2002-08-25/ 25-08-2002] |
||
+ | sub 2048R/0xAEBAADBEE208E2DD created: 2016-02-04 expires: 2018-02-03 usage: S |
||
− | | align="left" | 5.6948 |
||
+ | sub 2048R/0xE5151B7FDCA95A14 created: 2016-02-04 expires: 2018-02-03 usage: A |
||
− | | align="left" | >1000 |
||
+ | [ultimate] (1) Philippe Teuwen <phil@teuwen.org> |
||
− | | align="left" | - |
||
+ | [ unknown] (2). Philippe Teuwen <pteuwen@quarkslab.com> |
||
− | | align="left" | - |
||
+ | [ unknown] (3) [jpeg image of size 4266] |
||
− | | align="left" | 14 |
||
+ | |||
− | | align="left" | 14586 |
||
+ | gpg> uid 1 |
||
− | | align="left" | 6.5327 |
||
+ | gpg> primary |
||
− | |- |
||
+ | gpg> save |
||
− | | align="left" | |
||
+ | ==Almost there== |
||
− | [http://skylane.kjsl.com/~jharris/ka/2002-09-08/ 08-09-2002] |
||
+ | Exporting key |
||
− | | align="left" | 5.6979 |
||
+ | $ gpg --armor --export 9B554C36544C89BC > /media/phil/GNUPG/9B554C36544C89BC.asc |
||
− | | align="left" | >1000 |
||
+ | And pushing it to http://www.yobi.be/files/9B554C36544C89BC.asc |
||
− | | align="left" | - |
||
− | | align="left" | - |
||
− | | align="left" | 14 |
||
− | | align="left" | 14797 |
||
− | | align="left" | 6.5561 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2002-09-22/ 22-09-2002] |
||
− | | align="left" | 5.6648 |
||
− | | align="left" | >1000 |
||
− | | align="left" | - |
||
− | | align="left" | - |
||
− | | align="left" | 14 |
||
− | | align="left" | 14973 |
||
− | | align="left" | 6.5084 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2002-10-06/ 06-10-2002] |
||
− | | align="left" | 5.6414 |
||
− | | align="left" | >1000 |
||
− | | align="left" | - |
||
− | | align="left" | - |
||
− | | align="left" | 14 |
||
− | | align="left" | 15169 |
||
− | | align="left" | 6.5101 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2002-10-20/ 20-10-2002] |
||
− | | align="left" | 5.6296 |
||
− | | align="left" | >1000 |
||
− | | align="left" | 9 |
||
− | | align="left" | 12 |
||
− | | align="left" | 14 |
||
− | | align="left" | 15370 |
||
− | | align="left" | 6.5037 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2002-11-03/ 03-11-2002] |
||
− | | align="left" | 5.5183 |
||
− | | align="left" | >1000 |
||
− | | align="left" | 19 |
||
− | | align="left" | 27 |
||
− | | align="left" | 13 |
||
− | | align="left" | 15575 |
||
− | | align="left" | 6.5045 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2002-11-17/ 17-11-2002] |
||
− | | align="left" | 5.4787 |
||
− | | align="left" | >1000 |
||
− | | align="left" | 24 |
||
− | | align="left" | 27 |
||
− | | align="left" | 13 |
||
− | | align="left" | 15787 |
||
− | | align="left" | 6.5017 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2002-12-01/ 01-12-2002] |
||
− | | align="left" | 5.4420 |
||
− | | align="left" | >1000 |
||
− | | align="left" | 24 |
||
− | | align="left" | 27 |
||
− | | align="left" | 13 |
||
− | | align="left" | 15949 |
||
− | | align="left" | 6.4797 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2002-12-15/ 15-12-2002] |
||
− | | align="left" | 5.4373 |
||
− | | align="left" | >1000 |
||
− | | align="left" | 24 |
||
− | | align="left" | 27 |
||
− | | align="left" | 13 |
||
− | | align="left" | 16174 |
||
− | | align="left" | 6.4806 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2002-12-29/ 29-12-2002] |
||
− | | align="left" | 5.3922 |
||
− | | align="left" | >1000 |
||
− | | align="left" | 24 |
||
− | | align="left" | 27 |
||
− | | align="left" | 13 |
||
− | | align="left" | 16305 |
||
− | | align="left" | 6.4931 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-01-12/ 12-01-2003] |
||
− | | align="left" | 5.3865 |
||
− | | align="left" | >1000 |
||
− | | align="left" | 24 |
||
− | | align="left" | 27 |
||
− | | align="left" | 13 |
||
− | | align="left" | 16474 |
||
− | | align="left" | 6.4804 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-01-26/ 26-01-2003] |
||
− | | align="left" | 5.2183 |
||
− | | align="left" | >1000 |
||
− | | align="left" | 24 |
||
− | | align="left" | 27 |
||
− | | align="left" | 13 |
||
− | | align="left" | 16673 |
||
− | | align="left" | 6.4706 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-02-09/ 09-02-2003] |
||
− | | align="left" | 5.2173 |
||
− | | align="left" | >1000 |
||
− | | align="left" | 24 |
||
− | | align="left" | 27 |
||
− | | align="left" | 13 |
||
− | | align="left" | 16951 |
||
− | | align="left" | 6.4849 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-02-23/ 23-02-2003] |
||
− | | align="left" | 4.7102 |
||
− | | align="left" | 496 |
||
− | | align="left" | 43 |
||
− | | align="left" | 63 |
||
− | | align="left" | 13 |
||
− | | align="left" | 17338 |
||
− | | align="left" | 6.4773 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-03-09/ 09-03-2003] |
||
− | | align="left" | 4.7024 |
||
− | | align="left" | 507 |
||
− | | align="left" | 45 |
||
− | | align="left" | 63 |
||
− | | align="left" | 13 |
||
− | | align="left" | 17620 |
||
− | | align="left" | 6.4711 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-03-23/ 23-03-2003] |
||
− | | align="left" | 4.6933 |
||
− | | align="left" | 500 |
||
− | | align="left" | 46 |
||
− | | align="left" | 63 |
||
− | | align="left" | 13 |
||
− | | align="left" | 17861 |
||
− | | align="left" | 6.4675 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-04-06/ 06-04-2003] |
||
− | | align="left" | 4.6794 |
||
− | | align="left" | 481 |
||
− | | align="left" | 47 |
||
− | | align="left" | 63 |
||
− | | align="left" | 13 |
||
− | | align="left" | 18197 |
||
− | | align="left" | 6.6484 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-04-20/ 20-04-2003] |
||
− | | align="left" | 4.6373 |
||
− | | align="left" | 367 |
||
− | | align="left" | 51 |
||
− | | align="left" | 67 |
||
− | | align="left" | 13 |
||
− | | align="left" | 19075 |
||
− | | align="left" | 6.6624 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-05-04/ 04-05-2003] |
||
− | | align="left" | 4.6281 |
||
− | | align="left" | 358 |
||
− | | align="left" | 51 |
||
− | | align="left" | 67 |
||
− | | align="left" | 13 |
||
− | | align="left" | 19372 |
||
− | | align="left" | 6.6584 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-05-18/ 18-05-2003] |
||
− | | align="left" | 4.6027 |
||
− | | align="left" | 330 |
||
− | | align="left" | 51 |
||
− | | align="left" | 67 |
||
− | | align="left" | 13 |
||
− | | align="left" | 19641 |
||
− | | align="left" | 6.6410 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-06-01/ 01-06-2003] |
||
− | | align="left" | 4.6002 |
||
− | | align="left" | 331 |
||
− | | align="left" | 51 |
||
− | | align="left" | 67 |
||
− | | align="left" | 13 |
||
− | | align="left" | 19833 |
||
− | | align="left" | 6.6261 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-06-15/ 15-06-2003] |
||
− | | align="left" | 4.5854 |
||
− | | align="left" | 335 |
||
− | | align="left" | 52 |
||
− | | align="left" | 68 |
||
− | | align="left" | 13 |
||
− | | align="left" | 20095 |
||
− | | align="left" | 6.6038 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-06-29/ 29-06-2003] |
||
− | | align="left" | 4.5700 |
||
− | | align="left" | 330 |
||
− | | align="left" | 52 |
||
− | | align="left" | 68 |
||
− | | align="left" | 13 |
||
− | | align="left" | 20305 |
||
− | | align="left" | 6.5954 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-07-13/ 13-07-2003] |
||
− | | align="left" | 4.5531 |
||
− | | align="left" | 327 |
||
− | | align="left" | 52 |
||
− | | align="left" | 68 |
||
− | | align="left" | 13 |
||
− | | align="left" | 20602 |
||
− | | align="left" | 6.5762 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-07-27/ 27-07-2003] |
||
− | | align="left" | 4.5189 |
||
− | | align="left" | 419 |
||
− | | align="left" | 52 |
||
− | | align="left" | 68 |
||
− | | align="left" | 13 |
||
− | | align="left" | 20814 |
||
− | | align="left" | 6.5251 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-08-10/ 10-08-2003] |
||
− | | align="left" | 4.4803 |
||
− | | align="left" | 440 |
||
− | | align="left" | 52 |
||
− | | align="left" | 68 |
||
− | | align="left" | 13 |
||
− | | align="left" | 21025 |
||
− | | align="left" | 6.4861 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-08-24/ 24-08-2003] |
||
− | | align="left" | 4.4676 |
||
− | | align="left" | 461 |
||
− | | align="left" | 58 |
||
− | | align="left" | 75 |
||
− | | align="left" | 13 |
||
− | | align="left" | 21333 |
||
− | | align="left" | 6.4784 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-09-07/ 07-09-2003] |
||
− | | align="left" | 4.4565 |
||
− | | align="left" | 462 |
||
− | | align="left" | 59 |
||
− | | align="left" | 76 |
||
− | | align="left" | 13 |
||
− | | align="left" | 21487 |
||
− | | align="left" | 6.4721 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003-10-05/ 05-10-2003] |
||
− | | align="left" | 4.4456 |
||
− | | align="left" | 482 |
||
− | | align="left" | 59 |
||
− | | align="left" | 76 |
||
− | | align="left" | 13 |
||
− | | align="left" | 21843 |
||
− | | align="left" | 6.4762 |
||
− | |- |
||
− | | align="left" | |
||
− | [http://skylane.kjsl.com/~jharris/ka/2003--/ --2003] |
||
− | | align="left" | 4. |
||
− | | align="left" | - |
||
− | | align="left" | 58 |
||
− | | align="left" | 75 |
||
− | | align="left" | 13 |
||
− | | align="left" | - |
||
− | | align="left" | 6. |
||
− | |} |
||
+ | Back to the daily .gnupg |
||
− | </div> |
||
+ | $ sudo umount ~/.gnupg |
||
− | |||
+ | Changing default PINs |
||
− | #!/bin/bash |
||
+ | $ gpg --card-edit |
||
− | # gpg-setstats retrieves stats about the strongset & your key |
||
+ | gpg/card> admin |
||
− | REF="http://skylane.kjsl.com/~jharris/ka" |
||
+ | Admin commands are allowed |
||
− | MYKEY=${1:-"9AD7E3DB"} |
||
+ | 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 |
||
− | for URL in $(lynx -dump $REF|grep "$REF/200"|cut -c 7-53); do |
||
− | select q in "Stats for the ${URL#$REF}" "Skip" "Quit";do |
||
− | if [ "$q" == "Stats for the ${URL#$REF}" ]; then |
||
− | echo ======================================= |
||
− | echo Retrieve infos for ${URL#$REF}: |
||
− | wget -O - -q ${URL}other.txt |
||
− | wget -O - -q ${URL}status.txt|grep "strongly connected" |
||
− | wget -O - -q $URL${MYKEY:0:2}/$MYKEY|grep "^KeyID\|^Total\|^Mean\|^Farthest" |
||
− | echo -n "World Class:" |
||
− | lynx -dump ${URL}top1000table.html|grep $MYKEY|grep -v kjsl |
||
− | echo ======================================= |
||
− | break; fi |
||
− | if [ "$q" == "Skip" ]; then |
||
− | break; fi |
||
− | if [ "$q" == "Quit" ]; then |
||
− | exit; fi |
||
− | echo test $URL |
||
− | done |
||
− | done |
||
+ | $ gpg --card-status |
||
− | == Tips == |
||
+ | 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== |
||
− | === Pour fetcher ttes les UIDs qui ont signé une clé === |
||
+ | $ 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== |
||
− | for key in $(gpg --list-sigs $1|grep ^sig|cut -c 13-20|sort|uniq); |
||
+ | $ gpg --default-key 9ad7e3db --sign-key 9B554C36544C89BC |
||
− | do |
||
+ | Really sign all user IDs? (y/N) y |
||
− | gpg --recv-key $key |
||
+ | (3) I have done very careful checking. |
||
− | done |
||
+ | Your selection? (enter `?' for more information): 3 |
||
+ | Really sign? (y/N) y |
||
+ | $ gpg --send-key 9B554C36544C89BC |
||
− | === quintuple-agent === |
||
+ | As it's a pool I sent it 10x, rather than waiting them to all sync... |
||
− | |||
− | eval `q-agent &` |
||
− | q-client put 9AD7E3DB -t 3600 |
||
− | or directly use '''agpg''' instead of '''gpg''' |
||
+ | And also for those still using pgp.mit.edu: |
||
− | === Support de OpenPGP dans KMail: === |
||
+ | $ 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 |
||
− | * http://kmail.kde.org/kmail-pgpmime-howto.html |
||
+ | 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' ',' |
||
− | wget ftp://ftp.gnupg.org/gcrypt/alpha/aegypten/debian/libksba0_0.4.3-1_i386.deb |
||
− | dpkg -i libksba0_0.4.3-1_i386.deb |
||
− | wget ftp://ftp.gnupg.org/gcrypt/alpha/aegypten/debian/pinentry-gtk_0.6.3-1_i386.deb |
||
− | dpkg -i pinentry-gtk_0.6.3-1_i386.deb |
||
− | wget ftp://ftp.gnupg.org/gcrypt/alpha/aegypten/debian/gpgsm_0.3.9-1_i386.deb |
||
− | dpkg -i gpgsm_0.3.9-1_i386.deb |
||
− | gpg --rebuild-keydb-caches |
||
+ | <pre> |
||
− | Editer ~/.gnupg/gpg.conf -> use-agent <br />Dans KMail, Settings->Configure KMail->Security->Crypto Plugins et ajouter gpgme-openpgp.so plugin. <br />Laisser "update URL" vide et mettre un nom comme par ex. "OpenPGP", "location": /usr/lib/cryptplug/gpgme-opengpg.so |
||
+ | Date: 2016-02-04 |
||
+ | For a number of reasons[0], I've recently set up a new OpenPGP key, |
||
− | /usr/local/bin/gpg-kmail: |
||
+ | 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 |
||
− | #!/bin/bash |
||
+ | new key to be re-integrated into the web of trust. This message is |
||
− | launch_me(){ |
||
+ | signed by both keys to certify the transition. |
||
− | eval "$(gpg-agent --pinentry-program /usr/bin/pinentry-gtk --no-grab --default-cache-ttl 1800 )" |
||
− | kmail $* --nofork |
||
− | echo $GPG_AGENT_INFO|cut -d: -f2|xargs kill |
||
− | } |
||
− | launch_me $* & |
||
− | exit 0 |
||
+ | The old key was: |
||
− | ==Notes on signing-parties== |
||
− | Old notes: |
||
+ | pub 1024D/0x7A135F579AD7E3DB 2002-05-05 [expires: 2017-08-13] |
||
− | Pas mal d'infos sur http://skylane.kjsl.com/~jharris/keysigning.html<br />Ainsi que des exemples d'annonce par Adulau sur http://www.ael.be/action/gnupg/ et http://www.ael.be/action/gnupg/fosdem/<br />Mais un problème courant est la coordination physique des gens pour que chacun rencontre chacun. |
||
+ | 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: |
||
− | Soient N personnes prêtes à signer <br />Ces personnes se numérotent de 0 à N-1 |
||
+ | 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: |
||
− | |||
− | for (i=0;i<N;i++) |
||
− | { x signe (N-x+i)%N } |
||
+ | gpg --keyserver pool.sks-keyservers.net --recv-key F14883379E8DD09F03280E1B9B554C36544C89BC |
||
− | Puisque l'on fait ça N fois et que chacun ne doit signer que N-1 personnes, chacun sera passif lors d'UNE des itérations, simplement celle pour laquelle l'algo lui dit: x signe x <br />Bref tout le monde est occupé (N-1/N) % du temps :-) |
||
+ | If you already know my old key, you can now verify that the new key is |
||
− | Physiquement on peut se disposer en double file comme ceci: (ceux mis sur les bords ne signent pas) |
||
+ | signed by the old one: |
||
+ | gpg --check-sigs F14883379E8DD09F03280E1B9B554C36544C89BC |
||
− | |||
− | | i=0 | i=1 | i=2 | i=3 | i=4 | i=5 |
||
− | ----+---------+---------+---------+---------+---------+--------- |
||
− | | 1 2 | 1 2 | 2 3 | 2 3 | 3 4 | |
||
− | N=5 | 0 | | | | | 3 | 1 | | | | | 4 | 2 | | | |
||
− | | 4 3 | 0 4 | 0 4 | 1 0 | 1 0 | |
||
− | ----+---------+---------+---------+---------+---------+--------- |
||
− | | 1 2 | 1 2 3 | 2 3 | 2 3 4 | 3 4 | 3 4 5 |
||
− | N=6 | 0 | | 3 | | | | | 1 | | 4 | | | | | 2 | | 5 | | | | |
||
− | | 5 4 | 0 5 4 | 0 5 | 1 0 5 | 1 0 | 2 1 0 |
||
− | ----+---------+---------+---------+---------+---------+--------- |
||
+ | If you don't already know my old key, or you just want to be double |
||
− | Avantage de l'algo: lorsqu'on prépare les feuilles avec les fingerprints, on peut aussi préparer pour chacun l'ordre dans lequel il doit signer les autres: |
||
+ | extra paranoid, you can check the fingerprint against the one above: |
||
+ | gpg --fingerprint F14883379E8DD09F03280E1B9B554C36544C89BC |
||
− | |||
− | #!/bin/bash |
||
− | # argument: nbre total de personnes |
||
− | N=$1 |
||
− | for ((x=0;x<N;x++)); do |
||
− | echo -n "$x signera dans l'ordre: " |
||
− | for ((i=0;i<N;i++)); do |
||
− | echo -n "$((($N-$x+$i)%$N)) " |
||
− | done |
||
− | echo "" |
||
− | done |
||
+ | If you are satisfied that you've got the right key, and the UIDs match |
||
− | UPDATE: intéressant, lors du FOSDEM 2008 c'est en double-rang que l'on a effectivement progressé, avec 200 personnes sur la liste il y avait intéret à optimiser en effet ;-) |
||
+ | 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 |
||
− | There are some useful tools in Debian: |
||
− | apt-get install signing-party |
||
− | Here is an example based on my participation to the keysigning-party of FOSDEM 2008 |
||
+ | I'd like to receive your signatures on my key. You can either send me |
||
− | * Importing keys: the organizer provided a file with all the keys exported |
||
+ | an e-mail with the new signatures (if you have a functional MTA on |
||
− | tar xzvf keys.tgz |
||
+ | your system): |
||
− | for i in keys/*; do gpg --import $i;done |
||
+ | gpg --export F14883379E8DD09F03280E1B9B554C36544C89BC | \ |
||
− | * Preparing the given list of keys: the organizer provided a list such as in the examples provided here: /usr/share/doc/signing-party/gpgsigs/examples/. To prepare that file, compute its checksums and add the pictures when possible: |
||
+ | gpg --encrypt -r F14883379E8DD09F03280E1B9B554C36544C89BC --armor | \ |
||
− | gpgsigs --latex 9ad7e3db ksp-fosdem2008.txt ksp-fosdem2008 |
||
+ | mail -s 'OpenPGP Signatures' phil@teuwen.org |
||
− | latex ksp-fosdem2008 |
||
− | dvips ksp-fosdem2008.dvi |
||
− | ps2pdf ksp-fosdem2008.ps > ksp-fosdem2008.pdf |
||
+ | Additionally, I highly recommend that you implement a mechanism to |
||
− | * Preparing a stock of our own fingerprints, in case of... |
||
+ | keep your key material up-to-date so that you obtain the latest |
||
− | gpg-key2ps 9ad7e3db |ps2pdf - 9ad7e3db.pdf |
||
+ | 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 |
||
− | * But after all how was produced the list of fingerprints from the organizer? I created a script to generate such list: |
||
+ | practices doc, from which I stole most of the text for this transition |
||
− | <pre> |
||
+ | message ;-) |
||
− | #!/bin/bash |
||
+ | https://we.riseup.net/debian/openpgp-best-practices |
||
− | # License: GPLv3 |
||
− | # Copyright Philippe Teuwen <phil a teuwen o org> 2008 |
||
− | if [[ $# -ne 5 ]]; then |
||
− | cat <<EOF |
||
− | Usage: $0 input output datestring organizer title |
||
− | Or: $0 - output datestring organizer title |
||
− | to read from STDIN |
||
− | Example: |
||
− | echo 9AD7E3DB 54C12701 |\\ |
||
− | $0 - ksp-file.txt "20080222 1100" "Philippe Teuwen <phil a teuwen o org>" "my party 08" |
||
− | EOF |
||
− | exit 0 |
||
− | fi |
||
+ | Please let me know if you have any questions, or problems, and sorry |
||
− | input="$1" |
||
+ | for the inconvenience. |
||
− | [ "$input" == "-" ] && input=""; |
||
− | output="$2" |
||
− | date="$3" |
||
− | org="$4" |
||
− | title=$(echo "$5"|tr a-z A-Z|sed 's/\(.\)/\1 /g') |
||
+ | If you're curious, I've briefly documented all the steps using a Yubikey on my wiki [2]. |
||
− | exec > "$output" |
||
+ | Philippe Teuwen |
||
− | # Date of event |
||
− | LANG=C date --date="$date" +"%A, %B %e, %Y; %H:%M" |
||
− | # Organiser contact |
||
− | printf "%80s\n\n\n" "$org" |
||
− | # Title |
||
− | printf "%*s\n\n" $(((72+$(echo "$title"|wc -c))/2)) "$title" |
||
− | # Header |
||
− | cat <<EOF |
||
− | List of Participants (v 1.0) |
||
+ | 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 |
||
+ | </pre> |
||
+ | In an email signed with my old key... |
||
− | Here's what you have to do with this file: |
||
+ | ==Signing keys== |
||
− | (1) Print this file to paper. |
||
+ | To sign keys it requires the SD-Card. |
||
− | (2) Compute this file's MD5 checksum and optionally also its SHA1 checksum. |
||
− | gpg --print-md md5 $output (or use md5sum) |
||
− | gpg --print-md sha1 $output (or use sha1sum) |
||
− | (3) fill in the hash values on the printout. |
||
− | (4) Bring the printout, a pen, and proof of identity to the keysigningparty (and be on time!). |
||
+ | To enable it: |
||
− | MD5 Checksum: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ [ ] |
||
+ | 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== |
||
+ | <pre> |
||
+ | 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 |
||
+ | expire |
||
+ | 3y |
||
+ | 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 |
||
+ | </pre> |
||
+ | And pushing it to http://www.yobi.be/files/9B554C36544C89BC.asc |
||
+ | ==OpenSSH== |
||
− | SHA1 Checksum: ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ [ ] |
||
+ | 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== |
||
− | EOF |
||
+ | * [https://github.com/ANSSI-FR/SmartPGP SmartPGP], an implementation of the OpenPGP card 3.x specification in JavaCard (>=3.0.4) by ANSSI, including elliptic curves and RSA-4096 |
||
+ | <source lang=bash> |
||
− | k=0; |
||
+ | sudo apt-get install ant |
||
− | for i in $(cat $input); do |
||
+ | git clone git@github.com:martinpaljak/oracle_javacard_sdks.git |
||
− | k=$(($k+1)); |
||
+ | git clone git@github.com:ANSSI-FR/SmartPGP.git |
||
− | printf "\n%03d [ ] Fingerprint OK [ ] ID OK\n" $k; |
||
+ | cd SmartPGP |
||
− | gpg --fingerprint $i|grep -v "^sub"; |
||
+ | echo JAVACARD_HOME=$(pwd)/../oracle_javacard_sdks/jc304_kit > javacard.properties |
||
− | done |
||
+ | ant |
||
+ | # => ./build/fr/anssi/smartpgp/javacard/smartpgp.cap |
||
+ | </source> |
||
+ | |||
+ | 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 [https://github.com/ANSSI-FR/SmartPGP/issues/1 this issue] and the [https://github.com/ANSSI-FR/SmartPGP/tree/javacard-3.0.1 javacard-3.0.1] branch. |
||
+ | |||
+ | ==OpenPGP card 2.x JavaCard Applets== |
||
+ | See also https://subgraph.com/sgos/documentation/smartcards/index.fr.html |
||
+ | |||
+ | * [https://github.com/jderuiter/javacard-openpgpcard Joeri de Ruiter's implementation] |
||
+ | * [https://github.com/Yubico/ykneo-openpgp Yubikey NEO implementation] |
||
+ | ** [https://www.yubico.com/support/knowledge-base/categories/articles/reset-applet-yubikey/ Resetting the OpenPGP Applet] |
||
+ | * [https://github.com/FluffyKaon/OpenPGP-Card FluffyKaon implementation] |
||
+ | |||
+ | Yubikey and FluffyKaon implementations can be easily compiled from https://github.com/martinpaljak/AppletPlayground: |
||
+ | |||
+ | <source lang=bash> |
||
+ | git clone https://github.com/martinpaljak/AppletPlayground.git |
||
+ | cd AppletPlayground |
||
+ | ant |
||
+ | </source> |
||
+ | |||
+ | The author has also a [https://github.com/martinpaljak/GlobalPlatformPro GlobalPlatform tool] to inject the CAP into the card. |
||
+ | <br>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 [https://github.com/martinpaljak/GlobalPlatformPro/releases here]. |
||
+ | <br>Usage: |
||
+ | <source lang=bash> |
||
+ | java -jar gp.jar --help |
||
+ | </source> |
||
+ | |||
+ | Or using JCOP's jcshell: |
||
+ | <pre> |
||
+ | /card |
||
+ | auth |
||
+ | upload OpenPGPApplet.cap |
||
+ | install D27600012401 D2760001240102000000000000010000 |
||
+ | ctrl^d |
||
</pre> |
</pre> |
||
− | ===After the signing party=== |
||
− | * I clean the list ksp-fosdem2008.txt to keep only those I met. |
||
− | * I extract the fingerprints |
||
− | cat ksp-fosdem2008-ok.txt |grep fingerprint|sed 's/^.*= //;s/ //g'> ksp-fosdem2008-finger.txt |
||
− | * I configure caff, the first time it creates a template in ~/.caffrc which was nearly ok, I let only my usual public key, told to encrypt also for that key, activated the default email template, chose agpg as signing gpg program and finally chose a public keyserver: |
||
− | $CONFIG{'local-user'} = [ qw{7A135F579AD7E3DB} ]; |
||
− | $CONFIG{'also-encrypt-to'} = [ qw{7A135F579AD7E3DB} ]; |
||
− | $CONFIG{'gpg-sign'} = '/usr/bin/agpg'; |
||
− | $CONFIG{'keyserver'} = 'wwwkeys.pgp.net'; |
||
− | * I could not get caff working until I finally copied ~/.gnupg/pubring.gpg and ~/.gnupg/trustdb.gpg to ~/.caff/gnupghome/ then everything worked including import of new keys from the keyserver. |
||
− | * Signing only: |
||
− | caff --no-download --no-export-old --no-mail $(cat ksp-fosdem2008-finger.txt) |
||
− | yes / save (check twice the uids as you could have forgotten to remove it in ksp-fosdem2008-ok.txt) |
||
− | * Sending emails: |
||
− | caff --no-download --no-sign --no-export-old $(cat ksp-fosdem2008-finger.txt) |
||
− | * I got some undeliverable emails, some obviously being jabber ids, so I recovered the email content from ~/.caff/keys/2008-02-24 and sent it over jabber. |
||
+ | Testing the newly created OpenPGP card: |
||
− | * Short way for a professional signing-party using an internal keyserver: |
||
+ | <source lang=bash> |
||
+ | gpg --card-status |
||
+ | </source> |
||
+ | |||
+ | ==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: |
||
+ | |||
<pre> |
<pre> |
||
+ | $ gpg --card-status |
||
− | #!/bin/bash |
||
+ | 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] |
||
+ | </pre> |
||
+ | You may have problems getting it detected, especially if another card was used before. Reboot. |
||
− | for i in $(cat <<EOF |
||
+ | |||
− | 98851B2B8B5B43104A25ECA1A6F4CF46E9A11073 |
||
+ | Map the SDCard: |
||
− | 56CFE246BB33A42F1142646EE9E8031D67147274 |
||
+ | |||
− | ... |
||
+ | <source lang=bash> |
||
− | EOF) ; do |
||
− | + | $ pkill gpg-agent |
|
+ | # mount --bind /media/phil/GNUPG ~/.gnupg |
||
− | agpg -u nxp --sign-key $i; |
||
+ | </source> |
||
− | gpg --send-key $i; |
||
+ | Import again the keys (mainly the encryption key) moved to previous cards: |
||
− | done |
||
+ | <source lang=bash> |
||
+ | $ gpg --import < ~/.gnupg/9B554C36544C89BC-2016-02-04-47B68B62B62C8F88-secret.pgp |
||
+ | </source> |
||
+ | |||
+ | Create new sub-keys: |
||
+ | <source lang=bash> |
||
+ | $ 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 |
||
+ | </source> |
||
+ | |||
+ | Btw the notation "sec#" or "ssb#" means the key or subkey is not accessible (it's on another keyring or card). |
||
+ | <br>The notation "sec>" or "ssb>" means the card or subcard is stored on a card known to the system. |
||
+ | <br>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: |
||
+ | <source lang=bash> |
||
+ | $ 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 |
||
+ | </source> |
||
+ | |||
+ | The only solution I found was to clean the secret keyring, import again and sync card again: |
||
+ | |||
+ | <source lang=bash> |
||
+ | $ 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 |
||
+ | </source> |
||
+ | 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: |
||
+ | |||
+ | <source lang=bash> |
||
+ | $ 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 |
||
+ | </source> |
||
+ | |||
+ | Export the public key and unmount the SDCard: |
||
+ | <source lang=bash> |
||
+ | $ gpg --armor --export 9B554C36544C89BC > ~/.gnupg/9B554C36544C89BC_v3.asc |
||
+ | </source> |
||
+ | |||
+ | <source lang=bash> |
||
+ | $ pkill gpg-agent |
||
+ | $ sudo umount ~/.gnupg |
||
+ | $ gpg --import < /media/phil/GNUPG/9B554C36544C89BC_v3.asc |
||
+ | $ gpg --card-status |
||
+ | $ gpg --edit-key 9B554C36544C89BC |
||
+ | </source> |
||
+ | The encryption key is probably still linked to the previous card. |
||
+ | <br>Again, I didn't see a clean way to do it. |
||
+ | <br>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). |
||
+ | |||
+ | <source lang=bash> |
||
+ | cp /media/phil/GNUPG/private-keys-v1.d/AFE2DF0A021D08C752DE0ED0A8D020E8E57F4296.key ~/.gnupg/private-keys-v1.d |
||
+ | </source> |
||
+ | |||
+ | Now edit the key again, the encryption subkey should be associated with the new card. |
||
+ | |||
+ | Edit the card for the final adjustments: |
||
+ | |||
+ | <pre> |
||
+ | $ 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 |
||
</pre> |
</pre> |
||
− | * In case you mistype your passphrase with quintuple-agent (agpg), you've to delete the stored passphrase before trying again: |
||
− | q-client list |
||
− | q-client delete 54C12701 |
||
+ | Push the updated key to various keyservers. |
||
− | * Check who has signed your key: |
||
+ | <source lang=bash> |
||
− | gpglist 9AD7E3DB |
||
+ | gpg --keyserver hkps.pool.sks-keyservers.net --send-key 9B554C36544C89BC |
||
+ | </source> |
||
+ | |||
+ | ==[[GnuPG signing parties]]== |
||
+ | |||
+ | ==[[Short GnuPG reference card]]== |
||
+ | |||
+ | ==[[GnuPG old notes]]== |
Latest revision as of 21:00, 13 December 2022
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 expire 3y 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