How to manage GPG keys across multiple systems?
I'm new to using GnuPG and trying to understand how best to use it. I've reviewed Short, easy to understand explanation of GPG/PGP for nontechnical people?, but most guides explain PGP with a single-machine perspective.
I want to use GnuPG on three computing devices: a Linux PC, a Linux laptop, and an Android phone.
The fundamental use case is encrypting/decrypting email managed by an IMAP service, so all devices need the same private key for decryption.
I figure my choices are:
Just copy all my keys to the keyring on each device and rely mainly on the private key password for protection.
Create a master key (with --gen-key) to represent my identity, then create a separate disposable key (again with --gen-key) for encrypting/decrypting emails and signed with the master key. The former resides only on my PC, the latter is distributed to each device. As long as my mobile devices are not compromised, then the disposable key remains valid.
I may be overly paranoid and making this more complicated than it has to be, but humor me, please. I believe in not putting all your eggs in one basket.
The master key is supposed to be my digital identity. A lot of effort will be spent building trust around that identity, and I'd rather suffer the inconvenience of my paranoia than lose my key from carelessness and have to build trust around a new master key (maybe this isn't as bad as I think, but I am new to this).
I'm more likely to lose my laptop or my phone than my PC. If loss == compromise, then I'd rather lose an disposable key-pair (which I can revoke) than my master key-pair. I can always bestow the trust of my master key upon a new disposable key.
Sorry for the really long question. :-)
TL;DR
Is a password sufficient protection for storing my master private key across multiple devices?
Is my plan for option #2 feasible? Did I get something wrong or can it be improved?
If option #2 is a bad idea, then what are the best practices when using GnuPG for a single user across multiple devices?
Solution 1:
Well, this is a bit embarrassing. I've spent hours over the course of a week trying to figure this problem out, and the answer appears to lie with subkeys--a topic the GnuPG manual and FAQ glosses over.
While researching what subkeys are and why they might be used instead of --gen-key, I stumbled across this gem: http://wiki.debian.org/subkeys.
Debian's wiki explains how to implement option #2 (see OP) using a master key with subkeys, and further explains how to remove the master key from any system after storing it on a backup medium (e.g. a flash drive). The subkeys can then be distributed among my keyrings on each device.
Pros:
Does not rely mainly on password to protect master key,
If any system is compromised, the master key is not immediately available (unless I foolishly leave my flash drive plugged in, or attach said drive to a compromised system),
This is a practice implemented by the Debian development team.
Uses the subkey feature of GnuPG. Which seems a bit more organized than having a bunch of loose keys on your keyring, yes?
Relevant portion from Debian Subkey Wiki
-
Make backups of your existing GnuPG files ($HOME/.gnupg). Keep them safe. If something goes wrong during the following steps, you may need this to return to a known good place. (note: umask 077 will result in restrictive permissions for the backup.)
umask 077; tar -cf $HOME/gnupg-backup.tar -C $HOME .gnupg
-
Create a new subkey for signing.
- Find your key ID:
gpg --list-keys yourname
gpg --edit-key YOURMASTERKEYID
- At the
gpg>
prompt:addkey
- This asks for your passphrase, type it in.
- Choose the "RSA (sign only)" key type.
- It would be wise to choose 4096 (or 2048) bit key size.
- Choose an expiry date (you can rotate your subkeys more frequently than the master keys, or keep them for the life of the master key, with no expiry).
- GnuPG will (eventually) create a key, but you may have to wait for it to get enough entropy to do so.
- Save the key:
save
- Find your key ID:
You can repeat this, and create an "RSA (encrypt only)" sub key as well, if you like.
Now copy
$HOME/.gnupg
to your USB drives.-
Here comes the tricky part. You need to remove the private master key, and unfortunately GnuPG does not provide a convenient way to do that. We need to export the subkey, remove the private key, and import the subkey back.
- Export the subkeys:
gpg --export-secret-subkeys YOURMASTERKEYID >secret-subkeys
(to choose which subkeys to export, specify the subkey IDs each followed with an exclamation mark:gpg --export-secret-subkeys SUBKEYID! [SUBKEYID! ..]
) - Remove your master secret key:
gpg --delete-secret-key YOURMASTERKEYID
- Import the subkeys back:
gpg --import secret-subkeys
- Verify that
gpg -K
shows asec#
instead of justsec
for your private key. That means the secret key is not really there. (See the also the presence of a dummy OpenPGP packet in the output ofgpg --export-secret-key YOURMASTERKEYID | gpg --list-packets
). - Optionally, change the passphrase protecting the subkeys:
gpg --edit-key YOURMASTERKEYID passwd
. (Note that the private key material on the backup, including the private master key, will remain protected by the old passphrase.)
- Export the subkeys:
Your computer is now ready for normal use.
When you need to use the master keys, mount the encrypted USB drive, and set the GNUPGHOME environment variable:
export GNUPGHOME=/media/something
gpg -K
or use --home command-line argument:
gpg --home=/media/something -K
The latter command should now list your private key with sec
and not sec#
.
Multiple Subkeys per Machine vs. One Single Subkey for All Machines
Excerpt from Debian subkey wiki. Originally noted in comments. [Paraphrasing] and emphasis mine.
One might be tempted to have one subkey per machine so that you only need to exchange the potentially compromised subkey of that machine. In case of a single subkey used on all machines, it needs to be exchanged on all machines [when that single subkey is or suspected to be compromised].
But this only works for signing subkeys. If you have multiple encryption subkeys, gpg is said to encrypt only for the most recent encryption subkey and not for all known and not revoked encryption subkeys.
Solution 2:
As somebody who also doesn't like single points of failure (including master keys and especially passwords), this is the way I would do it. It allows for devices to operate via a web of trust, while still allowing decentralized identity.
I don't know if there's already an existing system for this, but I think it could probably be scrobbled together with a cron job and a few lines of Bash.
In this system, you have two classes of keypair: device keypairs and timeframe keypairs. One device keypair is generated for the user on each device, and stays on that device for its lifetime. A timeframe keypair is generated by a central server at routine intervals (monthly, daily, hourly - depends on how paranoid you want to be). The public key is announced publicly (the server itself having its own device keypair to sign with), and the private key is distributed encrypted with the public key of each device that is meant to have access to this key. (This distribution should be as private as possible, eg. having devices connect to the server directly.)
For signing messages, you would use the device key of whatever device you're sending the message from. If someone wants to send you a message, they can sign it with your current public timeframe key. (They should have an automated system to keep up with announcements.) You can then read their message from any device.
For reading older encrypted messages, older timeframe keypairs are backed up on each device according to an appropriate strategy (including the timeframe-keypair-generating server, if you so wish - again, depending on your level of paranoia), where you have another set of password-protected keypairs protecting the older keys (with however many passwords over time as you feel comfortable remembering).
If a device is stolen or otherwise compromised, you can use another one of your publically-trusted devices to create a publicly-signed message verifying your identity (by whatever means, eg. noting that you will be at a public meetup and/or or having a trusted friend verify you in person) and revoking the compromised device key and any timeframe keys it had access to. When revoking the key, you also remove the stolen device from the server's list of trusted devices (with a password and your trusted device key).
The policy for trusting newly-announced device keys should follow something like current trust policies- I believe an appropriate policy is to trust the generating server, a mobile device, and a big-and-heavy device, as it is hard to steal/infiltrate a user's phone, a desktop PC, and VPS in a concerted heist before the user notices.
If your server is compromised, you just revoke it by the same procedure described for any other compromised device (possibly with a stronger policy akin to the one for adding a new device), and use a re-secured or altogether new server (with a new device keypair) going forward.