Many tools that use cryptography on Linux and the internet revolve around the Pretty Good Privacy software standard (OpenPGP). The GNU Privacy Guard (GnuPG or GPG) is a popular free software implementation of this standard.
You can install GnuPG with its
gpg(1) frontend on Debian like so:
# apt-get install gnupg
You can do a lot of very cool things with GPG, but it boils down to four central ideas:
- Generation of keypairs, randomly-generated and mathematically linked pairs of files, one of which is kept permanently secret (the private key) and one of which is published (the public key). This is the basis of asymmetric key cryptography.
- Managing keys, both your own public and private key, along with other people’s public keys, so that you can verify others’ messages and files, or encrypt them so that only those people can read them. This might include publishing your public key to online keyservers, and getting people to sign it to confirm that the key is really yours.
- Signing files and messages with your private key to enable others to verify that a file or message was authored or sighted by you, and not edited in transmission over untrusted channels like the internet. The message itself remains readable to everybody.
- Encrypting files and messages with other people’s public keys, so that only those people can decrypt and read them with their private keys. You can also sign such messages with your own private key so that people can verify that it was sent by you.
We’ll run through the fundamentals of each of these. We won’t concern ourselves too much with the mathematics or algorithms behind these operations; the Wikipedia article for asymmetric key cryptography explains this very well for those curious for further details.
Generating a keypair
Let’s start by generating a 4096-bit RSA keypair, which should be more than sufficient for almost everyone at the time of writing. We’ll observe a few of the best practices recommended for the Debian developers.
Doing this on a private, up-to-date desktop machine is best, as it’s easier to generate entropy this way. It’s still possible on an SSH-only headless server, but you may have to resort to less cryptographically sound methods to generate proper randomness.
Create or edit the file
~/.gnupg/gpg.conf on your system, and add the
personal-digest-preferences SHA256 cert-digest-algo SHA256 default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
These lines tell GnuPG to use the cryptographically stronger SHA256 hashing algorithm for signatures in preference to the long-broken SHA1 algorithm.
With that done, we can get down to generating some keys:
$ gpg --gen-key
You will be prompted to choose the type of keypair you want. The default ought
RSA and RSA, which means we’ll generate one master key for signing, and
one subkey for encryption:
Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1
For the key length, choose the maximum 4096 bit RSA:
What keysize do you want? (2048) 4096 Requested keysize is 4096 bits
The expiry date is up to you. Good practice is to set an expiry date about a year out, because as long as you have access to the private key material, you can update the expiry date indefinitely, even if it’s already expired. For this particular example, we’ll set an expiry date one year out:
Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 1y Key expires at Wed 21 Jan 2015 12:24:57 NZDT Is this correct? (y/N) y
Next, we’re prompted for some basic information to name the key. In almost all circumstances you should use your real name, as without a real-world means to actually verify your identity, public keys are much less useful long-term. For the comment, you can include the key’s purpose, or your public aliases, or any other information relevant to the key:
Real name: Tom Ryder Email address: firstname.lastname@example.org Comment: Test Key Only You selected this USER-ID: "Tom Ryder (Test Key Only) <email@example.com>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
Next, we’re prompted for a passphrase to encrypt the key, so that if it ever falls into the wrong hands, nobody will be able to use it without knowing the passphrase.
You need a Passphrase to protect your secret key.
Choose a sequence of random words, or possibly a unique sentence you can easily memorise in any language, the longer the better. Don’t choose anything that might be feasibly guessable, like proverbs or movie quotes. You will also need to remember how you typed the passphrase exactly; I recommend using all-lowercase and no punctuation. Wikipedia has a few guidelines here.
You’ll need to type the passphrase twice to confirm it, and it won’t echo on your terminal, much as if you were typing a password.
Finally, the system will prompt us to generate some entropy:
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. Not enough random bytes available. Please do some other work to give the OS a chance to collect more entropy! (Need 283 more bytes)
This step is necessary for the computer to generate sufficient random
information to ensure that the private key being generated could not feasibly
be reproduced. Moving the mouse around and using the keyboard on a desktop
system is ideal, but generating any kind of hardware activity (including
spinning disks up) should do the trick. Running expensive
over a filesystem (with contents that couldn’t be reasonably predicted or
guessed) helps too.
This step benefits from patience. You might find discussion online about
forcing the use of the non-blocking PRNG random device
using a tool like
rngd(1). This definitely speeds up the process, but if
you’re going to be using your key for anything serious, I recommend actually
interacting with the computer and using hardware noise to seed the randomness
adequately, if you can.
When adequate entropy is read and the key generation is done, you’ll be presented with some details for your master signing key pair and its encrypting subkey pair, and the private and public keys for each are automatically added to your keyring for use:
gpg: /home/tom/.gnupg/trustdb.gpg: trustdb created gpg: key 040FE79B 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: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub 4096R/040FE79B 2013-03-23 Key fingerprint = 7A28 5ADA 7680 6813 48DF 401B 6207 438A 040F E79B uid Tom Ryder (Test Key Only) <firstname.lastname@example.org> sub 4096R/AA159E5B 2013-03-23
With this done, we have our own keys added to the private and public keychain:
$ gpg --list-secret-keys /home/tom/.gnupg/secring.gpg ---------------------------- sec 4096R/040FE79B 2013-03-23 uid Tom Ryder (Test Key Only) <email@example.com> ssb 4096R/AA159E5B 2013-03-23 $ gpg --list-public-keys /home/tom/.gnupg/pubring.gpg ---------------------------- pub 4096R/040FE79B 2013-03-23 uid Tom Ryder (Test Key Only) <firstname.lastname@example.org> sub 4096R/AA159E5B 2013-03-23
~/.gnupg contains the managed keys. It’s very, very important
to keep this directory private and to back it up securely, preferably to
removable media that you keep in some physically secure place. Don’t lose it!
In most contexts in GnuPG, you can refer to a key by the name of its owner, or
by its eight-digit hex ID. I prefer the latter method. Here, the short ID of my
main key is
040FE79B. While you shouldn’t use this for any actual
verification, it’s sufficiently unique that you can use it to identify
a specific key on your keyring with which you want to work.
For example, if we want to provide someone with a copy of our public key,
a friendly way to do so is to export it in ASCII format with
providing the appropriate key’s short ID:
$ gpg --armor --export 040FE79B > tom-ryder.public.asc
While you can export private keys the same way with
should never, ever provide anyone with your private key, so this shouldn’t be
After generating your keys, you should generate a revocation certificate:
$ gpg --output revoke.asc --gen-revoke 040FE79B sec 4096R/040FE79B 2013-03-23 Tom Ryder (Test Key Only) <email@example.com> 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? 1 Enter an optional description; end it with an empty line: > Reason for revocation: Key has been compromised (No description given) Is this okay? (y/N) y You need a passphrase to unlock the secret key for user: "Tom Ryder (Test Key Only) <firstname.lastname@example.org>" 4096-bit RSA key, ID 040FE79B, created 2013-03-23 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!
You should store the resulting
revoke.asc file somewhere safe. You can use
this certificate to revoke your key later on if the private key is ever
compromised, so that people know the key should no longer be used or trusted.
You may even like to print it out and keep a hard copy, as the output of
With the above setup done, we can proceed with some basic usage of GnuPG, as discussed in the next article.
In the output of both commands, you’ll note we actually have two private and
two public keys. The
sub line refers to the encryption subkey
automatically generated for you. The master key is used for cryptographic
signing, and the subkey for encryption; this is how GnuPG does things by
default with RSA keypairs.
For extra security, it might be appropriate to physically remove the master private key from your computer, and instead use a second generated subkey for signing files as well. This is desirable because it allows you to keep the master key secure on some removable media (preferably with a backup), and not loaded on your main computer in case you get compromised.
This means you can sign and encrypt files as normal with your signing subkey and encryption subkey. If those keys ever get compromised, you can simply revoke them and generate new ones with your uncompromised master key; everyone who has signed your public master key or otherwise indicated they trust it will not have to do that all over again.
For details on how to do this, I suggest reading the Debian Wiki article on subkey management. However, it’s not necessary for performing basic GPG operations.
Thanks to commenter coldtobi for recommending setting a key expiry.