GnuPG Tutorial

Posted on 18.01.2012 by Kim N. Lesmer. Last updated on 26.07.2016.
This is a minor tutorial in the usage of GnuPG to encrypt, decrypt, and sign emails and files. The examples provided in this tutorial has been used on Debian GNU/Linux, Devuan GNU/Linux, Arch Linux and Ubuntu GNU/Linux.

Table of contents

Introduction

Encryption is a method which allows information to be hidden so that it cannot be read without special knowledge or tools. Once this is done the information is encrypted. Decryption is a way to change an encrypted piece of information back into unencrypted form. This is called the decrypted form.

Encryption is used on the Internet. Web sites use encryption to protect private information. On the Internet, several encryption protocols are used, such as Secure Sockets Layer (SSL), IPsec, and SSH. They use the RSA encryption system and others. The protocol for protected web browsing is called HTTPS. Mostly URL encryption contain MD5 Algorithm. Various algorithms are available on the internet/market depending upon the need.

A digital signature or digital signature scheme is a mathematical scheme for demonstrating the authenticity of a digital message or document. A valid digital signature gives a recipient reason to believe that the message was created by a known sender, and that it was not altered in transit. Digital signatures are commonly used for software distribution, financial transactions, and in other cases where it is important to detect forgery or tampering.

A digital signature scheme typically consists of three algorithms:

  • A key generation algorithm that selects a private key uniformly at random from a set of possible private keys. The algorithm outputs the private key and a corresponding public key.
  • A signing algorithm that, given a message and a private key, produces a signature.
  • A signature verifying algorithm that, given a message, public key and a signature, either accepts or rejects the message's claim to authenticity.

GnuPG

GnuPG (GNU Privacy Guard) is a GPL Licensed alternative to the PGP suite of cryptographic software. GnuPG is a part of the Free Software Foundation's GNU software project, and has received major funding from the German government.

Although there exist various front-ends that provide GnuPG with a graphical user interface, this tutorial will only deal with the language-none version for GNU/Linux and BSD.

GnuPG encrypts messages using asymmetric key pairs individually generated by GnuPG users. Key-related cryptography refers to a cryptographic system requiring two separate keys, one to encrypt, and one to decrypt. Neither key will do both functions. One of these keys is public and the other key is kept private.

The public key is used to encrypt files or messages while the private key is used to decrypt files or messages.

GnuPG can also be used to sign files or messages with a digital signature.

Example:

Bob has created a key pair using GnuPG. He has both a private key and a public key. The private key is kept secret and safe and only he knows where it is. The public key is released and shared among Bob's friends.

Now, Alice wants to write Bob an encrypted email that only he can read. Alice uses Bob's public key to decrypt the email and sends the email to Bob. Bob receives the encrypted email from Alice and then uses his private key to decrypt the message so he can read it.

Bob then wants to thank Alice for her email, but he doesn't want the email he sends to be encrypted since it doesn't contain any private information, but Bob wants to make sure that Alice can validate that the email he sends her actually originated from him. Bob then uses his private key to sign the email, and Alice can use Bob's public key to verify that the signature is authentic.

Generating your keys

To create your private and public key pair you issue the following command:

$ gpg --gen-key

If you are using gnupg version 1.4.10 or newer, this will lead to a selection screen with the following options, where the one you should choose are bold:

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)
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)
Key does not expire at all
Is this correct? (y/N) y

Selecting "RSA and RSA" for key will enable both encryption and signing.

Regarding the keysize, the longer the key the more secure it is against brute-force attacks.

Next, follow the questions and fill out your name, email address, etc.

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"
Real name: Foo Bar
Email address: foo@bar.com
Comment: My GnuPG keys
You selected this USER-ID:
    "Foo Bar (My GnuPG keys) <foo@bar.com>"
...
You need a Passphrase to protect your secret key.

You will be asked for your passphrase twice. Usually, a short sentence or phrase that isn't easy to guess can be used, but make it as long as possible and have it contain both upper case letters, lower case letters, numbers, and signs - if possible.

I good way to create a strong password is to use a sentence from a favorite book, but not something people have heard you quoting many times, and then change it a bit by adding a number and a sign.

Last, you will be asked to type on the keyboard or do any of the things you normally do in order for randomization to take place. This is done so that the encryption algorithm has more human-entered elements, which, combined with the passphrase entered above, will result in the user's private key.

After you type your passphrase twice, the key will be generated. Please follow the instructions on the screen till you reach a screen similar to the one below.

gpg: key E3DF66D2 marked as ultimately trusted
public and secret key created and signed.
pub   4096R/E3DF66D2 2012-01-18
      Key fingerprint = 95BD 8377 2644 DD4F 28B5  2C37 0F6E 4CA6 E3DF 66D2
uid                  Foo Bar (My GnuPG keys) <foo@bar.com>
sub   4096R/259EA73B 2012-01-18

The key ID of this secret key pair is the hexadecimal number next to pub 4090R ie. in this case E3DF66D2

Edit ~/.gnupg/gpg.conf and set the new secret key as the default key using the ID of the key pair:

default-key E3DF66D2

You can but the line in the bottom of ~/.gnupg/gpg.conf

Get the ID of your key pair

If you ever need to view the ID of your key pair, it can be done with:

$ gpg --fingerprint foo@bar.com
pub   4096R/E3DF66D2 2012-01-18
      Key fingerprint = 95BD 8377 2644 DD4F 28B5  2C37 0F6E 4CA6 E3DF 66D2
uid                  Foo Bar (My GnuPG keys) <foo@bar.com>
sub   4096R/259EA73B 2012-01-18

Export your private key and keep it safe!

In order to prevent the need to generate a new key pair in case your computer fails, you should export your private key and keep is safe somewhere.

I recommend that you export your private key and then encrypt it using a password (could be the same as you are using for the private key itself).

By default the key is exported in a binary format, but this can be inconvenient when the key is to be sent though email or published on a web page. GnuPG therefore supports a command-line option --armor that causes output to be generated in an ASCII-armored format similar to uuencoded documents. In general, any output from GnuPG, e.g., keys, encrypted documents, and signatures, can be ASCII-armored by adding the --armor option.

Export the private key:

$ gpg --armor --output foo@bar.com_private_key.asc --export-secret-keys

Encrypt it using a password like this:

$ gpg -c --cipher-algo AES256 foo@bar.com_private_key.asc

Once you have entered a password twice a new file will be generated with the .gpg extension.

foo@bar.com_private_key.asc.gpg

This is your private key which has been encrypted using a password. You can now store the encrypted private key on an USB stick for example.

If you ever face a hard drive failure you don't need to generate a new key pair, you can just import your old private key.

To do so you first have to decrypt the exported key:

$ gpg foo@bar.com_private_key.asc.gpg

Once you have entered the correct password, your private key can be imported into a new installation of GnuPG:

$ gpg --import foo@bar.com_private_key.asc

If you don't protect your private key someone else might get his hands on the key and use it to decrypt something that was ment for your eyes only.

The public key

To communicate with others you must exchange public keys. To send your public key to a correspondent you must first export it. The command-line option --export is used to do this. It takes an additional argument identifying the public key to export.

$ gpg --armor --output foo@bar.com_public.asc --export foo@bar.com

In the above example you are using the email address to identify which public key you need to export, but you can also use the ID of the key pair:

$ gpg --armor --output foo@bar.com_public.asc --export E3DF66D2

You can now use your exported public key file foo@bar.com_public.asc to have others import it and send you encrypted messages or files.

Again, the above creates an ASCII-armored version of the signature because of the --armor option. To create a binary copy simply drop the --armor switch.

Importing and exporting public keys and creating a Web of Trust

In order to encrypt a message or a file to someone else using their public key, you first need to import their public key.

They will have to export their public keys, just like you did in the above example, and you must then exchange keys.

However, it is very important that you validate the person from whom you receive a public key.

You cannot simply download the public key of someone you know and then trust it really is his public key. If he uploaded it to a web server, what happens if a hacker gains access to the web server and then exchange the public key of your friend with his own public key?

Distributing this material alone, however, is a security risk since it is possible for an attacker to tamper with the key. The public key can be modified by adding or substituting keys, or by adding or changing user IDs. By tampering with a user ID, the attacker could change the user ID's email address to have email redirected to himself. By changing one of the encryption keys, the attacker would also be able to decrypt the messages redirected to him.

Using digital signatures is a solution to this problem. When data is signed by a private key, the corresponding public key is bound to the signed data. In other words, only the corresponding public key can be used to verify the signature and ensure that the data has not been modified. A public key can be protected from tampering by using its corresponding private master key to sign the public key components and user IDs, thus binding the components to the public master key. Signing public key components with the corresponding private master signing key is called self-signing, and a public key that has self-signed user IDs bound to it is called a certificate.

Signing public keys

If you communicate with another key owner, in person, or over the phone (if you know their voice), you know them to be who they say they are, and the key fingerprints match, then you may sign their key.

The most definitive way to refer to a specific key is to use the key's fingerprint. Key fingerprints are generated by performing a check sum on the actual content of a key. A fingerprint appears as a string of hexadecimal characters, sometimes separated by spaces or colons.

Let us assume that you have received a copy of your friend Bob's public key. Now, you can't meet Bob in person because you live far away from each other, but you can use the phone to validate and sign his public key.

First, get the fingerprint of Bob's public key without actually importing it:

$ gpg --with-fingerprint bob-public-key.asc
pub   1024D/D8FC66D2 2005-09-08
      Key fingerprint = 95BD 8377 2644 DD4F 28B5  2C37 0F6E 4CA6 D8FC 66D2
uid                  Bob The Builder (Tutorial key) <bob@example.com>
sub   2048g/389AA63E 2005-09-08

Next, you need to validate Bob's public key using his fingerprint.

Generally it is enough to use the last eight letters and numbers to ensure you are using the right key, but if you are actually meeting in person you should print out the fingerprint on a piece of paper and take it with you.

Update: 05.02.2012: A good friend of mine made me aware that the above statement is incorrect. It is important to verify the entire fingerprint and not just the last eight characters. The reason for this is because a man-in-the-middle attack could generate a "fuzzy fingerprint", which could fool someone into accepting a false fingerprint. Fuzzy Fingerprints Attacking Vulnerabilities in the Human Brain

Once Bob's public key has been verified, you need to import his key:

$ gpg --import bob-public-key.asc

Then you need to sign it:

$ gpg --sign-key bob@example.com

In order to assign trust to a key owner, you must assign the owner a value in your GnuPG trust database. You do this by editing their key:

$ gpg --edit-key bob@example.com

Type 'trust' and then follow the directions.

What do we use the key signing part for?

When you sign someone's public key you are effectively saying, "I testify that this key actually belongs to this person". People who trust you and your judgment will then accept the validity of that public key.

Let's say that Alice knows Bob only by email. She has never met Bob and she doesn't know the sound of his voice. Alice on the other hand knows you. If you export your signed version of Bob's public key and hand it over to Alice, she can verify that the public key really belongs to Bob because you have signed it, and Alice already has verified your public key, say in person for example.

Verifying signaturs of public keys

How do you then verify a public key that is signed by someone you know?

First, import the key that has been signed by someone you trust:

$ gpg --import bob-public-key.asc

Next, verify the key with:

$ gpg --check-sigs bob@example.com
pub   1024D/D8FC66D2 2005-09-08
uid                  Bob The Builder (Tutorial key) <bob@example.com>
sig3!       D8FC66D2 Bob The Builder (Tutorial key) <bob@example.com>
sig!        E3DF66D2 Foo Bar (My GnuPG keys) <foo@bar.com>
sub   2048g/389AA63E 2005-09-08

In the above example "Foo Bar" has signed "Bob The Builders" public key and since you know and trust the key of "Foo Bar" you can now also trust the key of "Bob The Builder".

By signing each others keys you are building a Web of Trust

A possible warning when using --check-sigs is something similar to this:

X signatures not checked due to missing keys

Where X is any kind of number.

That just means that the key you received has also been signed by other people, but since you don't have their public keys, you can't verify their signatures.

If the "Foo Bar" who had signed "Bob The Builders" public key was unknown to you, his signature would not be shown like the above, but would be included in the number of signatures not check due to missing keys.

Edit a key

You can edit a key using the command:

$ gpg --edit-key bob@example.com

This can be used to do many things on the key. Type help for a list of commands.

gpg> help
quit        quit this menu
save        save and quit
help        show this help
fpr         show key fingerprint
list        list key and user IDs
uid         select user ID N
key         select subkey N
check       check signatures
sign        sign selected user IDs [* see below for related commands]
lsign       sign selected user IDs locally
tsign       sign selected user IDs with a trust signature
nrsign      sign selected user IDs with a non-revocable signature
deluid      delete selected user IDs
delkey      delete selected subkeys
delsig      delete signatures from the selected user IDs
pref        list preferences (expert)
showpref    list preferences (verbose)
trust       change the ownertrust
revsig      revoke signatures on the selected user IDs
enable      enable key
disable     disable key
showphoto   show selected photo IDs
clean       compact unusable user IDs and remove unusable signatures from key
minimize    compact unusable user IDs and remove all signatures from key

To check the signatures added to Bob's public key type check

The result could look like this:

uid  Bob The Builder (Tutorial key) <bob@example.com>
sig!3        D8FC66D2 2011-11-28  [self-signature]
sig!         389AA63E 2012-01-15  Alice (I'm Alice)
sig!         2EA4B37F 2010-11-02  Brian Green

You might need to clean the key from unusable user IDs or unusable signatures, this can be done with the command clean

If you edit your own key you will get more commands/options and it will be possible to, for example, add a photo to your public key.

Type quit to exit the command prompt.

Export your public key

You can export your public key this way:

$ gpg --output foo@bar.com_public_key.gpg --export foo@bar.com

If you would like it to be an ASCII-armored version add the option --armor like this:

$ gpg --armor --output foo@bar.com_public_key.asc --export foo@bar.com

Delete a key

If a user, for some reason, looses his private key and needs to generate a new key pair, you would need to delete his old key before you import his new one.

This can be done like this:

$ gpg --delete-keys bob@example.com

Encrypting and decrypting files using keys

Lets say you want to send Bob a text file encrypted with his public key. You can do that this way:

$ gpg -e -r bob@example.com somefile.txt

The above command will result in the creation of a file called somefile.txt.gpg and it's the encrypted version (using Bob's public key) of somefile.txt The file is in a binary format.

If you would like it to be an ASCII-armored version add an a like this:

$ gpg -ea -r bob@example.com somefile.txt

Or you could achive the same with:

$ gpg --armor -e -r bob@example.com somefile.txt

Use whatever option combination that suits you best.

Once Bob receives the file he can decrypt it using the following command:

$ gpg somefile.txt.gpg

Encrypting and decrypting email

For those not interested in the technical parts about how email are encrypted and decrypted can skip this part.

There are two main standards for sending PGP-secured email.

  • The original, called PGP-inline, involves taking the plain-text message body, giving it to the PGP program (in our case GnuPG), and sending the output as a new message body. The email client then takes the message body and gives it to PGP to decode.
  • The new and improved, called PGP/MIME or OpenPGP/MIME. It's a solution that was developed using MIME.

The old method, PGP-inline, has two main downsides.

  • People who aren't using encryption don't like to see gibberish in the message if they receive a signed email.
  • Attachments don't get encrypted or signed.

When you sign an email using PGP-inline it adds a bunch of gibberish to the message and changes any lines that begin with a dash (-). People who don't use PGP will see all that gibberish in the email message.

If you are signing emails using PGP/MIME the signature gets attached to the email instead, and people who don't use PGP won't see any gibberish.

Another great advantage of PGP/MIME is that it automatically includes attachments and can easily deal with formatted and non-English messages.

In a PGP/MIME encrypted message, attachments appear just as they would in a non-encrypted message. The recipient can view or save them just as they would any other attachment.

In contrast, with PGP-inline you have to encrypt the file you want to attach manually and then attach it, it adds the extra step of encrypting or decrypting, both for the sender and the recipient.

Email clients supporting cryptography

This part in the tutorial about the email clients is taken from the Ubuntu website about GnuPG and is not at all inclusive.

Claws Mail

Claws Mail is my favorite email client and it has a strong support for GnuPG.

Claws Mail supports OpenPGP through the plugin claws-mail-pgpmime, don't use claws-mail-pgpinline as it's the "old" way to deal with encrypted email.

# apt-get install claws-mail-pgpmime

The plugin may have to be loaded manually after installing it.

  • Open Claws Mail and select Configuration -> Plugins
  • If PGP/Core and PGP/MIME are in the Plugins dialogue box, the plugins are loaded correctly.
  • Otherwise, click on the Load Plugin button towards the bottom of the window. In the file selection dialogue, select pgpmime.so and click the Open button.

When Claws Mail tries to open encrypted e-mail, the program will prompt for your key's passphrase and then show the e-mail with the decrypted message.

Thunderbird

Thunderbird supports OpenPGP through the enigmail plugin.

# apt-get install enigmail

Configure OpenPGP support in Thunderbird under Enigmail->Preferences and add under GnuPG executable path. The path for GnuPG is /usr/bin/gpg.

Evolution

Evolution has built-in support for OpenPGP. Look under the Security tab when you edit accounts.

  • Open Evolution and go to Edit->Preferences.
  • Choose your email account, click on it, and then click Edit.
  • Click on the security tab.
  • In the PGP/GPG Key ID: box, paste your KEY-ID.
  • Click OK. Click Close.
  • If you want to use your key in any new email, simply click on the Security menu item in your new mail message, and then click on PGP Sign.

Mutt

  • Create a ~/.mutt directory and copy this file into it: /usr/share/doc/mutt/examples/gpg.rc
  • Append this line to the muttrc configuration file.
source ~/.mutt/gpg.rc # Use GPG

Using webmail services such as Hushmail

Encrypted webmail can't be trusted. You basically have to use a passphrase that is so good that you don't mind having your (encrypted) private key publicly available.

An important point to consider is that the administrators of the service will have access to your encrypted private key.

Another importent point to consider is that the webserver has read access to the key. The problem is that if anyone gets root access to the server, the only thing between your private key and an attacker is your passphrase.

The only way to have securely encrypted email is to store the private key on your own private local machine. A webmail service simply cannot guarantee you anything.

Further reading

The GnuPG Manual Key signing party