One of the cornerstones of my home infrastructure is GPG. GPG is an encryption/signing/authentication tool, and is used for all three purposes in my network. I use it for SSH connections (authentication), my password store (encryption/decryption), and signing emails. For added security, this is done via a smart card purchased from kernel concepts. My personal machine is a Lenovo T420, and I use the embedded card reader.
Setting up the card with current versions of GPG (2.0.21 as of today) is different from most tutorials you can find. This is due to GPG versions 2.0.18 and later supporting 4096 bit keys for the kernel concept smart card. Before you start configuring the card, you need to install all necessary software. For me, that is:
gpg2, gpgsm, pcscd, gnupg-agent
Once those are installed, you can begin to create your keys. While these instructions assume you have a smart card, they will work with minimal effort even absent one.
[email protected] ~ % gpg --card-status Application ID ...: D276000124010200000500001ABD0000 Version ..........: 2.0 Manufacturer .....: ZeitControl Serial number ....: 00001ABD Name of cardholder: [not set] Language prefs ...: en Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Max. PIN lengths .: 32 32 32 PIN retry counter : 3 0 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
Your smart card information should look similar to this. First, here’s some important safety information: The card accepts up to three wrong PINs in a row and then block, until unblocked by the admin PIN. Three wrong admin PINs and your card bricks itself, to prevent access to the information. Don’t do this, unless you need to know that the information has to be destroyed.
Now we’ll begin to edit the smart card. With your card, you can either transfer pre-existing keys to the card, or generate new ones. I am going to generate keys on the card, as demonstrated below.
[email protected] ~ % gpg --card-edit Application ID ...: D276000124010200000500001ABD0000 Version ..........: 2.0 Manufacturer .....: ZeitControl Serial number ....: 00001ABD Name of cardholder: [not set] Language prefs ...: en Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Max. PIN lengths .: 32 32 32 PIN retry counter : 3 0 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] Command> admin Admin commands are allowed Command> name Cardholder's surname: O'Connell Cardholder's given name: Patrick gpg: 3 Admin PIN attempts remaining before card is permanently locked Admin PIN gpg: gpg-agent is not available in this session Command> lang Language preferences: en Command> sex Sex ((M)ale, (F)emale or space): m gpg/card> generate Admin-only command gpg/card> admin Admin commands are allowed gpg/card> generate Make off-card backup of encryption key? (Y/n) y What keysize do you want for the Signature key? (2048) 4096 The card will now be re-configured to generate a key of 4096 bits NOTE: There is no guarantee that the card supports the requested size. If the key generation does not succeed, please check the documentation of your card to see what sizes are allowed. What keysize do you want for the Encryption key? (2048) 4096 The card will now be re-configured to generate a key of 4096 bits What keysize do you want for the Authentication key? (2048) 4096 The card will now be re-configured to generate a key of 4096 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) 0 Key does not expire at all Is this correct? (y/N) y GnuPG needs to construct a <a class="zem_slink" title="User identifier" href="http://en.wikipedia.org/wiki/User_identifier" target="_blank" rel="wikipedia">user ID</a> to identify your key. Real name: Patrick O'Connell Email address: [email protected] Comment: You selected this USER-ID: "Patrick O'Connell <[email protected]>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O You need a Passphrase to protect your secret key. gpg: NOTE: backup of card key saved to `/home//.gnupg/sk_16A65751AA333CD9.gpg' gpg: key F7D12196 marked as ultimately trusted public and secret key created and signed. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u pub 4096R/F7D12196 2013-09-22 Key fingerprint = 0059 EA3C CC54 D92F E203 DE29 12F2 C901 F7D1 2196 uid Patrick O'Connell <[email protected]> sub 4096R/43DDE8B2 2013-09-22 sub 4096R/AA333CD9 2013-09-22 gpg/card> quit
With those initial keys set up, we can now configure some settings. The first we want to get to is changing the preferences for how to do signatures.
[email protected] [2] ~ % gpg --edit-key [email protected] gpg (GnuPG) 2.0.21; Copyright (C) 2013 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Secret key is available. pub 2048R/14F0F412 created: 2013-07-27 expires: never usage: SC trust: ultimate validity: ultimate sub 2048R/61DBC4A3 created: 2013-07-27 expires: never usage: A sub 2048R/2081E3C6 created: 2013-07-27 expires: never usage: E [ultimate] (1). Patrick O'Connell <[email protected]> gpg> uid 1 pub 2048R/14F0F412 created: 2013-07-27 expires: never usage: SC trust: ultimate validity: ultimate sub 2048R/61DBC4A3 created: 2013-07-27 expires: never usage: A sub 2048R/2081E3C6 created: 2013-07-27 expires: never usage: E [ultimate] (1)* Patrick O'Connell <[email protected]> gpg> setpref SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed Set preference list to: Cipher: AES256, AES192, AES, CAST5, 3DES Digest: SHA512, SHA384, SHA256, SHA224, SHA1 Compression: ZLIB, BZIP2, ZIP, Uncompressed Features: MDC, Keyserver no-modify Really update the preferences for the selected user IDs? (y/N) y pub 4096R/F7D12196 created: 2013-09-22 expires: never usage: SC trust: ultimate validity: ultimate sub 4096R/43DDE8B2 created: 2013-09-22 expires: never usage: A sub 4096R/AA333CD9 created: 2013-09-22 expires: never usage: E [ultimate] (1)* Patrick O'Connell <[email protected]> gpg> save [email protected] ~ %
You can now add any other uids you need to your key. This can be done with the edit-keys command followed by the adduid command.
[email protected] ~ % gpg --edit-key [email protected] gpg (GnuPG) 2.0.21; Copyright (C) 2013 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Secret key is available. pub 4096R/F7D12196 created: 2013-09-22 expires: never usage: SC trust: ultimate validity: ultimate sub 4096R/43DDE8B2 created: 2013-09-22 expires: never usage: A sub 4096R/AA333CD9 created: 2013-09-22 expires: never usage: E [ultimate] (1). Patrick O'Connell <[email protected]> gpg> adduid Real name: Patrick O'Connell Email address: Comment: You selected this USER-ID: "Patrick O'Connell " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O pub 4096R/F7D12196 created: 2013-09-22 expires: never usage: SC trust: ultimate validity: ultimate sub 4096R/43DDE8B2 created: 2013-09-22 expires: never usage: A sub 4096R/AA333CD9 created: 2013-09-22 expires: never usage: E [ultimate] (1) Patrick O'Connell <[email protected]> [ unknown] (2). Patrick O'Connell gpg> save [email protected] ~ %
Initializing the card generated both authentication and encryption subkeys, and the next stage is to add a separate signing subkey. Subkeys are keys that cannot sign other keys, but depend on the initial keys set up for their trust. These are used to avoid having to use the ultimately trusted key everywhere. This also helps demonstrate how to add other subkeys later, if needed.
[email protected] ~ % gpg --edit-key [email protected] gpg (GnuPG) 2.0.21; Copyright (C) 2013 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Secret key is available. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub 4096R/F7D12196 created: 2013-09-22 expires: never usage: SC trust: ultimate validity: ultimate sub 4096R/43DDE8B2 created: 2013-09-22 expires: never usage: A sub 4096R/AA333CD9 created: 2013-09-22 expires: never usage: E [ultimate] (1). Patrick O'Connell [ultimate] (2) Patrick O'Connell <[email protected]> gpg> uid 2 pub 4096R/F7D12196 created: 2013-09-22 expires: never usage: SC trust: ultimate validity: ultimate sub 4096R/43DDE8B2 created: 2013-09-22 expires: never usage: A sub 4096R/AA333CD9 created: 2013-09-22 expires: never usage: E [ultimate] (1). Patrick O'Connell [ultimate] (2)* Patrick O'Connell <[email protected]> gpg> addkey Secret parts of primary key are stored on-card. Please select what kind of key you want: (3) DSA (sign only) (4) RSA (sign only) (5) Elgamal (encrypt only) (6) RSA (encrypt only) Your selection? 4 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) 4096 Requested keysize is 4096 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) 0 Key does not expire at all Is this correct? (y/N) y Really create? (y/N) y You need a Passphrase to protect your secret key. We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. pub 4096R/F7D12196 created: 2013-09-22 expires: never usage: SC trust: ultimate validity: ultimate sub 4096R/43DDE8B2 created: 2013-09-22 expires: never usage: A sub 4096R/AA333CD9 created: 2013-09-22 expires: never usage: E sub 4096R/31FED8A5 created: 2013-09-22 expires: never usage: S [ultimate] (1). Patrick O'Connell [ultimate] (2)* Patrick O'Connell <[email protected]> gpg> save [email protected] ~ %
The next step, and critical to the security of the entire GPG infrastructure, is creating revocation certificates. These can be posted to GPG key servers to announce that you cannot trust them anymore, typically if you lose physical control over your smart card. This is the only possible way to revoke the trust of a certificate, so do not skip this step!
[email protected] ~ % gpg --output [email protected] --gen-revoke [email protected] sec 4096R/F7D12196 2013-09-22 Patrick O'Connell <[email protected]> Create a revocation certificate for this key? (y/N) y Please select the reason for the revocation: 0 = No reason specified 1 = Key has been compromised 2 = Key is superseded 3 = Key is no longer used Q = Cancel (Probably you want to select 1 here) Your decision? 0 Enter an optional description; end it with an empty line: > Reason for revocation: No reason specified (No description given) Is this okay? (y/N) y ASCII armored output forced. Revocation certificate created.Please move it to a medium which you can hide away; if Mallory gets access to this certificate he can use it to make your key unusable. It is smart to print this certificate and store it away, just in case your media become unreadable. But have some caution: The print system of your machine might store the data and make it available to others! [email protected] ~ %
Next, we will upload our GPG key to remote key servers. This allows for people to gain access to our public keys, and is necessary if anyone is going to send us encrypted information, or give us access via our authentication keys. For this I will just send you to the GPG instructions as to how to do so, in case they change in future versions.
Now, we can start actually using the keys we have just generated. First, lets set up SSH. For SSH, using a key is the only way I recommend connections. You do not want to allow password authentication to any machine you control. Additionally, you want to only be able to log in with a non-root user, and then authenticate to higher permissions. There is countless documentation as to why this is true, but in general someone is going to be able to crack your passwords far easier than any key-based login. We will use our authentication subkey, which for me is 43DDE8B2. The following commands, run on a remote machine, would immediately allow us to gain immediate SSH access to that machine.
[email protected] ~ % gpg --recv-key 43DDE8B2 [email protected] ~ % gpgkey2ssh 43DDE8B2 >> ~/.ssh/authorized_keys [email protected] ~ %
As for the password store, password managers are useful and allow for much easier management of per-account passwords. I do not re-use passwords between websites, which is always nice when you find out that a service has been compromised, I do not have to scurry around and figure out what websites I need to change things for. What I like most about using zx2c4’s Pass for this is that it integrates with GPG. Trust doesn’t have to be given to another service, nor do I need to embed any other plugins.
This sets up a fairly sound foundation for future work, such as enabling automatic GPG signing or encryption of email. It also encourages you to use more secure passwords for other services, and prevents security incident avalanches.
Related articles
- Creating The Perfect GPG Keypair (alexcabal.com)
- Bruce Schneier just changed his PGP key to 4096 bits (news.ycombinator.com)
- Setting Up Automated GPG Email Encryption With Thunderbird (thenciee.wordpress.com)
Pingback: Basic Technology Security | Aeria Gloris
Pingback: Securing SSH | Aeria Gloris