sorenpoulsen.com header

Encryption with GnuPG on Ubuntu

The GnuPG commandline tool can encrypt any data for storage or transport. It uses a hybrid scheme of Public Key Crypto and symmetric encryption.

Symmetric encryption is fast and can encrypt any arbitrary size of data.

Public Key Crypto is slow and only encrypts data shorter than its Public key, but has strong key management properties and can also be used for digital signatures.

A hybrid scheme combines the best of both.

In the use of the GnuPG commandline tool the Public Key Crypto scheme is very much visible to the end user while symmetric encryption is not. So let's introduce how the former works.

How Public Key Crypto Works

In Public Key Crypto a subject, being a person, system or organization, has a key pair consisting of a public and private key. There is a mathematical relation between the keys and mathematical system for encryption with these two fundamental rules:

1) data encrypted with the public key can only be decrypted with the private key (and vice versa).

2) the private key cannot be derived from the public key.

Software such as GnuPG leverage these to support key management, encryption and also digital signatures.

Public Key Cryptography with GnuPGAs the name suggests the public key can be shared with anyone. You could for instance share your public key with a friend by email or simply post it on a public website.

Once in possession of your public key, your friend can now use it to encrypt a file and send it to you by email. The file is then decrypted by you using your private key.

Email is an inherently unsafe channel of communication and an attacker could have intercepted both your public key and the encrypted file - but no harm done.

Because of rule no. 1 the attacker cannot decrypt the intercepted data with the intercepted public key.

And because of rule no. 2 the attacker cannot derive the private key from the intercepted public key.

It seems the attacker is defeated without the private key which is never sent over an unsafe channel of communication.

However the attacker could have replaced your public key while in transit to your friend with the attacker's own public key. If your friend is tricked into using the attacker's public key then the attacker can decrypt the intercepted data using the attacker's own private key. This is called a man in the middle attack.

Later in this post we shall see a simple way that your friend can assert the authenticity of the public key by checking the fingerprint of the key. A more involved method is to use the Web of Trust but it is not covered in this post.

So time to get hands-on with GnuPG on Ubuntu.

Install GnuPG

Ubuntu life is easy:

sudo apt-get install gnupg

Create a key

First let's create your personal key pair. GnuPG will take you through a number of steps to set it up.

gpg --gen-key

Select the key type (1) RSA and RSA.

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

A keysize of 2048 bits is still considered adequate, and if you some day wish to move your key to a safer storage, such as a OpenPGP smartcard, then the card may have a max size of 2048 bits, so let's stay with that for now.

What keysize do you want? (2048) 2048

Understanding expiration periods is difficult without understanding the concept of a primary key and its subkeys, which I will introduce in another post. For now just create the key without an expiration period, it can be changed later on.

Please specify how long the key should be valid.
0 = key does not expire
<n> d = 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) 0

Your friends will import your public key into their keyring and when they want to use the key they identify it by name, email and a comment. Make sure these uniquely identify who you are.

Real name: Bob
Email address: bob@example.com
Comment: Aka bobmeister

You will be asked for a new passphrase which is critically important because it protects your private key.

GnuPG maintains two keyrings, one for public keys and one for private keys. Whenever you use a private key to decrypt something, GnuPG will prompt for the passphrase.

Chose a passphrase of 3 to 5 random words. They should be random in the sense that one should not be able to find this sequence of words in any book. Google "random passphrase generator" if you need help to generate something random.

Enter passphrase: WarmWilly-WANKA2wants&warts

When you are through, the keys are stored in a public and private keyring file under ~/.gnupg:

drwx------   2 bob bob 4096 jul  5 14:08 ./
drwxr-xr-x 100 bob bob 4096 jul 5 09:35 ../
-rw------- 1 bob bob 9398 mar 26 20:44 gpg.conf
-rw------- 1 bob bob 3707 jul 5 13:56 pubring.gpg
-rw------- 1 bob bob 2577 jul 5 13:34 secring.gpg
-rw------- 1 bob bob 1360 jul 5 13:56 trustdb.gpg

Scenario 1: Encrypting a file for secure backup

Now that you have a key pair let's start out with a simple scenario - to encrypt a file that only you can decrypt. This is often used to secure backups.

The -e option names the file to encrypt and the -o option the encrypted output file. The -r option tells GnuPG who the recipient is. Encryption is performed with the recipient's public key. Choose yourself as recipient (in this scenario that's you Bob!).

Bob> echo "secret message" > message.txt
Bob> gpg -o message.encrypted -r bob@example.com -e message.txt

Using the email address to select the associated key is a general pattern when using GnuPG. If you can't remember the email address of a public key, then list the keys in your public keyring with this command:

Bob> gpg -k

Use the -d option to decrypt the file using your private key:

Bob> gpg -o message.txt -d message.encrypted

The new message.txt file should contain the same unencrypted message we started out with.

Scenario 2: Encrypting a file for transport

In this next scenario we encrypt a file that only your friend Joe can decrypt.

First Joe exports his public key to a file and sends it to you:

Joe> gpg -o joespublickey.asc --export -a joe@example.com

You import his public key into your keyring:

Bob> gpg --import joespublickey.asc

An attacker may have replaced Joe's public key with the attacker's own public key while it was in transit to you. To verify that it is actually the authentic public key, you list the fingerprint of the key, call him on the phone and read the fingerprint out.

Bob> gpg --fingerprint joe@example.com
pub 2048R/675F7FA8 2015-03-25
Key fingerprint = BD9F 2FB3 91B0 D6CA 97EF 957F 9C15 570B 675E 7FA7
uid Bob <bob@example.com>
sub 2048R/7A11F3A0 2015-03-25

If he agrees that it is indeed his key, then sign his key with your own private key to make it trusted. Note you can skip this step but GnuPG will warn you that his key is not trusted when you use it.

Bob> gpg --sign-key joe@example.com

Encrypt a file with his public key:

Bob> echo "secret message to joe" > message.txt
Bob> gpg -o message.encrypted -r joe@example.com -e message.txt

Send the encrypted file to Joe who can now decrypt it using his own private key:

Joe> gpg -o message.txt -d message.encrypted

Backup

Backup all the files stored in the ~/.gnupg folder. Although the private keyring is already protected by a passphrase, you could add another layer of security, by storing the backup on an encrypted USB flash drive.

Securing the private key further

Having the private key stored on the day-to-day machine poses a risk that the key might be stolen. A hacker could break into your machine, copy the private keyring and steal your passphrase with a keylogger.

To further secure the private key you can move it off the harddisk onto a OpenGPG Smartcard or a OpenPGP USB device such as the Nitrokey Pro. Once stored on the device, the private key can still be used, but no longer copied.

{{model.usr.name}}
{{cmt.user.name}}
{{cmt.user.name}}
{{childcmt.user.name}}
{{childcmt.user.name}}