Knowledge for the World

How to send and receive encrypted messages using GPG

Another tale of Alice and Bob

GPG (GnuPG) is a free and complete implementation of PGP (pretty good privacy). It is a tool used for encrypting, decrypting, and signing messages (or many forms of data). In this guide, we'll cover the steps to send and receive secure messages using GPG.

For this guide, we'll assume you want to exchange messages with your good friend, Alice.


First, GPG must be installed.


sudo apt-get install gnupg


sudo yum install gnupg


Using Homebrew.

brew install gnupg

The first thing we'll do is generate a pair of keys. To do this run:

gpg --gen-key

You will be guided through the process of generating the key pair. Your keys will be associated with your name and email address.

The private key is protected with a password. Use a strong password, and store that password somewhere secure (password manager and/or physical safe).

Your public key is just that: public. This is the key you can share with anyone.

The private and public keys are generated as a pair, which means they can only be used with their counterpart. The public key, which can be distributed to others, is used to encrypt messages intended for you. So when Alice wants to send you a message, she'll encrypt the message using your public key. And only the accompanying private key can decrypt that message.

At this point, Alice should follow this step and generate her key pair as well.


Now that you've created your key pair, we'll export the public key.

gpg --export EMAIL > pubkey.asc

The email address you used when you generated your key will be used to export the key as well. This command will generate a file called pubkey.asc. In the future, Alice will import this key and use it to encrypt messages for you.

Alice should follow this step and export her public key as well.


Now you can exchange public keys with Alice.

Note: When sending your key, it's important that Alice can trust that the key came from you and likewise, that you can trust that the real Alice received your key. This is a security challenge of it's own and is outside the scope of this guide. Just be sure to use a communication channel that is trustworthy enough.


Now that you have Alice's key file, you can import it using:

gpg --import alicepubkey.asc

At this point, you may want to trust Alice's public key. To do so use:

gpg --edit-key Alice

Then in the gpg prompt, type:


Then select the level of trust 1-5.


Let's list the keys in our keyring to verify that the correct keys exist.

gpg --list-keys

You should see output similar to this:

$ gpg --list-keys

pub   rsa2048 2017-05-03 [SC] [expires: 2019-05-03]
uid           [ultimate] Tyler <>
sub   rsa2048 2017-05-03 [E] [expires: 2019-05-03]

pub   rsa2048 2017-08-01 [SC] [expires: 2019-08-01]
uid           [ultimate] Alice <>
sub   rsa2048 2017-08-01 [E] [expires: 2019-08-01]

Assuming your message for Alice is stored in a file called message-for-alice, we can encrypt the message with the following command:

gpg --encrypt --recipient message-for-alice

This will encrypt your message using Alice's public key. The encrypted message will be saved as a new file called message-for-alice.gpg.

Now you can send the encrypted message to Alice.


Upon receiving a message from Alice, you can decrypt the message using your private key.

gpg --decrypt message-for-me.gpg

This will print the message to the console. To write the message to a file use:

gpg --decrypt --output message message-for-me.gpg

Signing a message allows the recipient to verify that the message was not modified during transmission. This is especially important when the message is sent over an insecure channel.

For this example, we'll sign the message that we encrypted for Alice.

gpg --output message.sig --sign message-for-alice.gpg

This will create a file called message.sig, which is a signed version of the encrypted message.


To verify the signed message, use:

gpg --decrypt --output message.gpg message.sig

This assumes that the message was first encrypted, then signed. You should see something like the following output that verifies the digital signature:

gpg: Signature made Tue Nov 21 21:51:45 2017 PST
gpg:                using RSA key A43BE404B2E42BF68C3860A329BD72BDE33C02E9
gpg: Good signature from "Tyler <>"

The output file, message.gpg is still encrypted. So you can use the same method to decrypt:

gpg --decrypt --output message message.gpg

There are a handful of frontends listed on the site, and I have not tested many of them. But if you're timid on the command line and would like to find a GUI, there are a few available for each operating system.