Linux Security Basics: How to Encrypt and Sign Files with GnuPG

By Emmett Dulaney

Linux comes with the GNU Privacy Guard (GnuPG or GPG) encryption and authentication utility. With GnuPG, you can create your public and private key pair on your Linux system, encrypt files with your key, and digitally sign a message to authenticate that it’s from you. If you send a digitally signed message to someone who has your public key, the recipient can verify that you signed the message.

Understanding public key encryption

The basic idea behind public key encryption is to use a pair of keys — one private and the other public — that are related but can’t be used to guess one from the other. Anything encrypted with the private key can be decrypted only with the corresponding public key, and vice versa. The public key is for distribution to other people; you keep the private key in a safe place.

You can use public key encryption to communicate securely with others. Let’s try an example. Suppose that Alice wants to send secure messages to Bob. Each person generates public key and private key pairs, after which they exchange their public keys. When Alice wants to send a message to Bob, she encrypts the message by using Bob’s public key and sends the encrypted message to him. Now the message is secure from eavesdropping, because only Bob’s private key can decrypt the message, and only Bob has that key. When Bob receives the message, he uses his private key to decrypt the message and read it.

At this point, you might say, “Wait a minute! How does Bob know that the message really came from Alice? What if someone else uses Bob’s public key and sends a message as though it came from Alice?” This situation is where digital signatures come in.

Understanding digital signatures

The purpose of digital (electronic) signatures is the same as that of pen-and-ink signatures, but how you sign digitally is different. Unlike a pen-and-ink signature, your digital signature depends on the message you’re signing. The first step in creating a digital signature is applying a mathematical function to the message and reducing it to a fixed-size message digest (also called a hash or a fingerprint). No matter how big your message is, the message digest is usually 128 or 160 bits, depending on the hashing function.

The next step is applying public key encryption. Simply encrypt the message digest with your private key, and you get the digital signature for the message. Typically, the digital signature is added to the end of the message, and voilà — you get an electronically signed message.

What good does the digital signature do? Well, anyone who wants to verify that the message is indeed signed by you takes your public key and decrypts the digital signature. What that person gets is the message digest (the encrypted hash) of the message. Then he or she applies the same hash function to the message and compares the computed hash with the decrypted value. If the two match, then no one has tampered with the message. Because your public key was used to verify the signature, the message must have been signed with the private key known only to you, so the message must be from you!

In the theoretical scenario in which Alice sends private messages to Bob, Alice can digitally sign her message to make sure that Bob can tell that the message is really from her.

Here’s how Alice sends her private message to Bob with the assurance that Bob can tell it’s from her:

  1. Alice uses software to compute the message digest of the message and then encrypts the digest by using her private key — her digital signature for the message.
  2. Alice encrypts the message (again, using some convenient software and Bob’s public key).
  3. She sends both the encrypted message and the digital signature to Bob.
  4. Bob decrypts the message, using his private key.
  5. Bob decrypts the digital signature, using Alice’s public key, which gives him the message digest.
  6. Bob computes the message digest of the message and compares it with what he got by decrypting the digital signature.
  7. If the two message digests match, Bob can be sure that the message really came from Alice.

Using GPG in a Linux system

GPG includes the tools you need to use public key encryption and digital signatures. You can figure out how to use GPG gradually as you begin using encryption. The following information shows some of the typical tasks you can perform with GPG.

Generating the key pair in Linux

The steps for generating the key pairs are as follows:

  1. Type gpg –gen-key. 

    If you’re using GPG for the first time, it creates a .gnupg directory in your home directory and a file named gpg.conf in that directory. Then it asks what kind of keys you want:

    Please select what kind of key you want:
    (1) DSA and ElGamal (default)
    (2) DSA (sign only)
    (4) RSA (sign only)
    Your selection?
  2. Press Enter for the default choice, which is good enough. 

    GPG prompts you for the key size (the number of bits).

  3. Press Enter again to accept the default value of 2,048 bits. 

    GPG asks you when the keys expire. The default is to never expire.

  4. If the default is what you want (and why not?), press Enter.
  5. When GPG asks whether you really want the keys to never expire, press the Y key to confirm. 

    GPG prompts you for your name, your email address, and a comment to make it easier to associate the key pair with your name.

  6. Type each piece of requested information, and press Enter.
  7. When GPG gives you a chance to change the information or confirm it, confirm by typing o and pressing Enter. 

    GPG prompts you for a passphrase that protects your private key.

  8. Type a long phrase that includes lowercase and uppercase letters, numbers, and punctuation marks — the longer the better — and then press Enter. 

    Be careful to choose a passphrase that you can remember easily.

     

    GPG generates the keys. It may ask you to perform some work on the PC so that the random-number generator can generate enough random numbers for the key-generation process.

Exchanging keys using Linux

To communicate with others, you have to give them your public key. You also have to get public keys from those who may send you a message (or when someone who might sign a file and you want to verify the signature). GPG keeps the public keys in your key ring. (The key ring is simply the public keys stored in a file, but the name sounds nice because everyone has a key ring in the real world, and these keys are keys of a sort.) To list the keys in your key ring, type

gpg --list-keys

To send your public key to someone or to place it on a website, you have to export the key to a file. The best way is to put the key in what GPG documentation calls ASCII-armored format, with a command like this:

gpg --armor --export kdualney@insightbb.com > kdulaneykey.asc

This command saves the public key in ASCII-armored format (which looks like garbled text) in the file named kdulaneykey.asc. You replace the email address with your email address (the one you used when you created the key) and replace the output filename with something different.

After you export the public key to a file, you can mail that file to others or place it on a website for use by others.

When you import a key from someone, you typically get it in ASCII-armored format as well. If you have a us-cert@us-cert.gov GPG public key in a file named uscertkey.asc, you import it into the key ring with the following command:

gpg --import uscertkey.asc

Use the gpg --list-keys command to verify that the key is in your key ring. Here’s what you might see when typing gpg –list-keys on the system:

/home/kdulaney/.gnupg/pubring.gpg
-----------------------------
pub 1024D/7B38A728 2018-08-28
uid Kristin Dulaney <kdulaney@insightbb.com>
sub 2048g/3BD6D418 2018-08-28
pub 2048R/F0E187D0 2019-09-08 [expires: 2019-10-01]
uid US-CERT Operations Key <us-cert@us-cert.gov>

The next step is checking the fingerprint of the new key. Type the following command to get the fingerprint of the US-CERT key:

gpg --fingerprint us-cert@us-cert.gov

GPG prints the fingerprint, as follows:

pub 2048R/F0E187D0 2018-09-08 [expires: 2019-10-01]

Key fingerprint = 049F E3BA 240B 4CF1 3A76 06DC 1868 49EC F0E1 87D0

uid US-CERT Operations Key <us-cert@us-cert.gov>

At this point, you need to verify the key fingerprint with someone at the US-CERT organization.

If you think that the key fingerprint is good, you can sign the key and validate it. Here’s the command you use to sign the key:

gpg --sign-key us-cert@us-cert.gov

GPG asks for confirmation and then prompts you for your passphrase. After that, GPG signs the key.

Because key verification and signing are potential weak links in GPG, be careful about what keys you sign. By signing a key, you say that you trust the key to be from that person or organization.

Signing a file in Linux

You may find signing files to be useful if you send a file to someone and want to assure the recipient that no one tampered with the file and that you did in fact send the file. GPG makes signing a file easy. You can compress and sign a file named message with the following command:

gpg -o message.sig -s message

To verify the signature, type

gpg --verify message.sig

To get back the original document, type

gpg -o message --decrypt message.sig

Sometimes, you don’t care about keeping a message secret, but you want to sign it to indicate that the message is from you. In such a case, you can generate and append a clear-text signature with the following command:

gpg -o message.asc --clearsign message

This command appends a clear-text signature to the text message. Here’s a typical clear-text signature block:

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
iD8DBQFDEhAtaHWlHHs4pygRAhiqAJ9Qj0pPMgKVBuokDyUZaEYVsp6RIQCfaoBm
9zCwrSAG9mo2DXJvbKS3ri8=
=2uc/
-----END PGP SIGNATURE-----

When a message has a clear-text signature appended, you can use GPG to verify the signature with the following command:

gpg --verify message.asc

If you indeed signed the message, the last line of the output says that the signature is good.

Encrypting and decrypting documents in Linux

To encrypt a message meant for a recipient, you can use the --encrypt (or -e) GPG command. Here’s how you might encrypt a message for US-CERT by using its GPG key:

gpg -o message.gpg -e -r us-cert@us-cert.gov message

The message is encrypted with the US-CERT public key (without a signature, but you can add the signature with the -s command).

When US-CERT receives the message.gpg file, the recipient must decrypt it by using US-CERT’s private key. Here’s the command that someone at US-CERT can use:

gpg -o message --decrypt message.gpg

Then GPG prompts for the passphrase to unlock the US-CERT private key, decrypts the message, and saves the output in the file named message.

If you want to encrypt a file that no one else has to decrypt, you can use GPG to perform symmetric encryption. In this case, you provide a passphrase to encrypt the file with the following GPG command:

gpg -o secret.gpg -c somefile

GPG prompts you for the passphrase and asks you to repeat the passphrase (to make sure that you didn’t mistype anything). Then GPG encrypts the file, using a key generated from the passphrase.

To decrypt a file encrypted with a symmetric key, type

gpg -o myfile --decrypt secret.gpg

GPG prompts you for the passphrase. If you enter the correct passphrase, GPG decrypts the file and saves the output (in this example) in the file named myfile.