A friend of mine recently reminded me of the OpenPGP smartcard v2, and told me that it was perfectly able to handle 4096 bit RSA keys (provided you have GnuPG v2.0.18+). I had the opportunity to play with one a little, and notice it was super easy to use it for ssh authentication, especially since I already use gpg-agent as my ssh-agent (it should be easy to use a purely software authentication key as ssh key with GnuPG 2.1). So I decided to buy two of them and try to switch my main key (0x71ef0ba8) to it.
The cards arrived this weekend, and I was able to play with it a little. I didn't log every command I typed, but it was pretty easy, in the end. What I decided to do was to use one smartcard for every day usage, and one only for key signing. So basically, I would generate three (signing, encryption, authentication) subkeys, put them on smartcard 1, then put the primary key on smartcard 2. Then erase the private parts, and only keep them on smartcards.
In case it interests people, here the somehow detailed steps. Note that everywhere 'gpg' means 'gpg2' on Debian, we really need GnuPG v2 for correct smartcard handling. You'd better use gpg-agent too, although it doesn't seem mandatory.
- make a backup! As we're gonna play with private parts (!), it's
always a good idea to have backups. And it'll be useful to have one
later, in case there's a problem with the smartcards. You can do a
copy of your complete ~/.gnupg folder, but I simply did:
corsac@scapa: umask 066 corsac@scapa: gpg -o 71ef0ba8.gpg --export-secret-keys 71ef0ba8
- Add three subkeys. Skip this is you already have subkeys (you
usually already have an encryption subkey, but I wanted to switch
to a new one too) --expert is needed in order to chose
capabilities.
corsac@scapa: gpg --expert --edit-key 71ef0ba8 gpg> addkey Please select what kind of key you want: (3) DSA (sign only) (4) RSA (sign only) (5) Elgamal (encrypt only) (6) RSA (encrypt only) (7) DSA (set your own capabilities) (8) RSA (set your own capabilities) Your selection? 8 Possible actions for a RSA key: Sign Encrypt Authenticate Current allowed actions: Sign Encrypt (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? e Possible actions for a RSA key: Sign Encrypt Authenticate Current allowed actions: Sign (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? Q RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) 1y Key expires at dim. 27 oct. 2013 20:38:44 CET Is this correct? (y/N) y Really create? (y/N) y We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy.
Repeat this for encryption and authentication subkeys. Then save and send the key to keyserversgpg> save corsac@scapa: gpg --send-keys 71ef0ba8
- Next, we'll switch to the smartcard part. I use a Gemalto
PC ExpressCard reader which is perfectly recognized under
Debian. You just need few tools:
root@scapa: ~# apt-get install pcscd scdaemon
Plug the reader, insert the card, make sure it's detected:corsac@scapa: gpg --card-status Application ID ...: D2760001240102000005000016A10000 Version ..........: 2.0 Manufacturer .....: ZeitControl ...
You can edit various parameter (name etc.) and change the PINs using gpg:corsac@scapa: gpg --change-pin corsac@scapa: gpg --card-edit
- Then we'll put the subkeys in the first smartcard. It might be
a good idea to export again the private keys for backups.
corsac@scapa: gpg -o 71ef0ba8.gpg --export-secret-keys 71ef0ba8
- We'll now use the keytocard gpg command to move the
private parts on the smartcard:
corsac@scapa: gpg --edit-key 71ef0ba8 gpg> key 1 # select encryption subkey gpg> keytocard gpg> key 2 # select signature subkey gpg> keytocard gpg> key 3 # select authentication subkey gpg> keytocard gpg> save
A quick check on the card now reveals that it's populated:corsac@scapa: gpg --card-status Application ID ...: D2760001240102000005000016A10000 Version ..........: 2.0 Manufacturer .....: ZeitControl Serial number ....: 000016A1 Name of cardholder: Yves-Alexis Perez Language prefs ...: fr Sex ..............: unspecified URL of public key : http://www.corsac.net/71ef0ba8.asc Login data .......: corsac Signature PIN ....: forced Key attributes ...: 2048R 2048R 2048R Max. PIN lengths .: 32 32 32 PIN retry counter : 3 3 3 Signature counter : 7 Signature key ....: 9745 B022 7323 81FE 9E7E AFF5 6DDB 53F2 A675 C0A5 created ....: 2012-10-27 11:24:07 Encryption key....: F7E0 078F EA1A 5F23 92E0 20B3 A83A D136 D98D 0D9F created ....: 2012-10-27 11:27:01 Authentication key: 8CFD D478 AB4A 16F8 F0EC CD33 24E2 3B5C CC0E 273D created ....: 2012-10-17 14:29:18 General key info..: pub 2048R/A675C0A5 2012-10-27 Yves-Alexis Perez sec> 4096R/71EF0BA8 created: 2009-05-06 expires: never card-no: 0005 000016A2 ssb 4096g/36E31BD8 created: 2009-05-06 expires: never ssb> 2048R/CC0E273D created: 2012-10-17 expires: 2013-10-27 card-no: 0005 000016A1 ssb> 2048R/A675C0A5 created: 2012-10-27 expires: 2013-10-27 card-no: 0005 000016A1 ssb> 2048R/D98D0D9F created: 2012-10-27 expires: 2013-10-27 card-no: 0005 000016A1
-
At that point, the private part is replaced by a stub in the secret keyring, so when you export them, you only export stubs which you can then use anywhere without actually giving your private key. So now is a good idea to export the subkeys so you can import them on other boxes:
corsac@scapa: gpg -o 71ef0ba8-subkeys.gpg --export-secret-subkeys 71ef0ba8
Note that only the subkeys private parts have been moved to the card, not the primary one, so you're still able to sign keys. Here, you have multiple choices. You can simply erase the private key (and later re-import the stubs) and use the offline copy made above when you need to sign another key.
- What I did is something else. I've put the primary key on my
second OpenPGP smartcard. That way, I won't lose it, it'll be kept
safely in my house, but still be on a hardware token where it won't
come out.
The procedure for doing is so is exactly the same as above. First take a backup (in case you didn't do it first, do it now since after the keytocard command you won't have a backup of your primary key and there'll be no way to extract it from the smartcard. Then put the new smartcard in the reader, edit the key (don't select a subkey) and run the keytocard command.
After that, running gpg --export-secret-keys will export the stub and not the private part of your primary key.
In the end, it seems that everything is running fine. Only issue is that scdaemon is sometime not behaving nicely (especially after a card change or or suspend/resume cycle). I didn't yet report a bug but you might want to kill it in case it's stuck.
You can also use the authentication subkey for ssh logins. When the card is inserted, the authentication subkey appears automatically (through the magic of gpg-agent):
corsac@scapa: ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EA... cardno:0005000016A1
And now you can add it to your various authorized_keys and use the smartcard for SSH.