Background

Almost a decade ago I wrote this article showing how to use PGP to secure your emails. Today I decide to rewrite it, to make it useful in 2025, and to instruct people who might want to encrypt their communication with me but don't know how.

This is a complete rewrite, expect more than just PGP in emails. I will use my own key as an example, feel free to test what you learned with it.

The Core Concept: How PGP Works

Before we dive in, let's understand the main idea. PGP (Pretty Good Privacy) uses a system called "public-key cryptography". This system solves two big problems: privacy (encryption) and authenticity (signing).

It does this by giving you a key pair, which consists of two related digital keys:

  1. Your Public Key:
  2. Think of this as a padlock or an open mailbox slot.
  3. You can give this key to everyone. You can put it on your website, your Twitter bio, or a public keyserver.
  4. People use your public key to encrypt messages for you. Anyone can "lock" a message with your public key, but only you can unlock it.
  5. People also use your public key to verify your digital signature.

  6. Your Secret Key (or Private Key):

  7. Think of this as the one and only key that opens your padlock or your mailbox.
  8. You must NEVER share this key with anyone. It's protected by a strong passphrase that you will create.
  9. You use your secret key to decrypt messages that were encrypted with your public key.
  10. You also use your secret key to digitally sign messages, proving they came from you.

In summary:

  • To Encrypt (Privacy): You get your friend's public key and use it to lock a message. Only your friend can unlock it with their secret key.
  • To Sign (Authenticity): You use your secret key to create a unique signature for a message. Anyone can use your public key to check that the signature is valid and that the message hasn't been changed.

Install GnuPG

GnuPG (Gnu Privacy Guard) is the most popular, free, and open-source software implementation of PGP.

Linux

Typically gpg is pre-installed since most package managers depend on it. You can check your version:

~
❯ gpg --version
gpg (GnuPG) 2.4.0
libgcrypt 1.10.2-unknown
...

If your gpg version is old or not present, follow your distro's documentation to install or upgrade it (e.g., sudo apt install gnupg or sudo dnf install gnupg).

Windows

Install the complete Gpg4win suite, which includes GnuPG and helpful tools.

MacOS

Install GPG Tools (also known as Mac GPG).

How to Use GPG

Generate Your Keypair

First, you need to create your own public and secret keypair.

~
❯ gpg --full-generate-key

This command will walk you through a few questions. The default options are modern, secure, and highly recommended.

  1. Please select what kind of key you want:
  2. Choose (9) ECC (sign and encrypt) *default*. This is a modern and fast elliptic-curve key.

  3. Please select which elliptic curve you want:

  4. Choose (1) Curve 25519 *default*. This is a fast, secure, and modern curve.

  5. Please specify how long the key should be valid:

  6. 0 = key does not expire is the simplest option.
  7. If you choose an expiration (like 1y for one year), you will need to remember to extend it later. For beginners, 0 (no expiration) is fine.

  8. Key is valid for? (0) 0

  9. Is this correct? (y/N) y

  10. GnuPG needs to construct a user ID to identify your key.

  11. Real name: Enter your name (e.g., jm33-test).
  12. Email address: Enter the email you'll use this key with (e.g., jm33.me@gmail.com).
  13. Comment: Optional (e.g., Demo).
  14. You'll see a User-ID like: "jm33-test (Demo) <jm33.me@gmail.com>".
  15. Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

  16. Create a Passphrase:

  17. You will be prompted to enter a passphrase. This is critically important.
  18. This passphrase is the only thing protecting your secret key. If someone steals your key file, they can't use it without this passphrase.
  19. Make it long, strong, and memorable. Do not forget it.

GPG will then generate your keys. It might ask you to move your mouse or type on the keyboard to generate "entropy" (randomness).

...
public and secret key created and signed.

pub   ed25519 2023-06-04 [SC]
      00416191C169BCF410712173E9FAF7E43E456E68
uid                      jm33-test (Demo) <jm33.me@gmail.com>
sub   cv25519 2023-06-04 [E]

The long string 00416191C169BCF410712173E9FAF7E43E456E68 is your key's fingerprint. This is a unique ID for your key.

You can view it again at any time:

❯ gpg --fingerprint jm33.me@gmail.com
pub   ed25519 2023-06-04 [SC]
      0041 6191 C169 BCF4 1071  2173 E9FA F7E4 3E45 6E68
uid           [ultimate] jm33-test (Demo) <jm33.me@gmail.com>
sub   cv25519 2023-06-04 [E]

Share Your Public Key

Now that you have a key, you need to let people get your public key so they can send you encrypted messages.

Option 1: Send the key as a file (Recommended)

You can "export" your public key to a file and email it, host it on your website, or send it via chat.

# This exports your public key (identified by your email) to a file named "my-key.asc"
gpg --export --armor --output my-key.asc jm33.me@gmail.com

You can then send my-key.asc to your contacts.

Option 2: Use a Keyserver

A keyserver is like a public phone book for PGP keys.

# Upload your key (using its fingerprint) to a public server
gpg --keyserver hkps://keyserver.ubuntu.com --send-key 00416191C169BCF410712173E9FAF7E43E456E68

Warning: Be aware that uploading to a public keyserver is permanent. You cannot delete it.

Obtain and Trust a Recipient's Public Key

To send an encrypted message to someone, you first need their public key.

Step 1: Get the Key

  • From a file: If they sent you their key.asc file, you just import it:

bash gpg --import key.asc

  • From a keyserver: If you know their key's fingerprint or ID, you can download it:

bash # Replace the fingerprint with your recipient's gpg --keyserver hkps://keyserver.ubuntu.com --recv-key 00416191C169BCF410712173E9FAF7E43E456E68

Step 2: Verify the Key (CRUCIAL)

How do you know the key you just downloaded actually belongs to your friend? An attacker could have uploaded a fake key to a keyserver.

You must verify the fingerprint "out-of-band" (meaning, through a different channel).

  1. Ask gpg to show you the fingerprint of the key you just imported:

bash gpg --fingerprint user@example.com

  1. Call your friend, text them, or meet them in person and ask them, "What is your PGP key's fingerprint?"
  2. Compare what they tell you with what you see on your screen. If they match exactly, you have the right key.

Step 3: Trust the Key

Once you've verified the key, you need to tell GPG that you trust it. This is done by "signing" their key with your own secret key. This is like making a note in your system that says "I've checked this, and it's legit."

# Start the key-editing process
gpg --edit-key user@example.com

# In the GPG prompt, type:
gpg> fpr
# (This shows the fingerprint again, just to be sure)

gpg> sign
# (This signs their key with your secret key. You'll be asked for your passphrase)

gpg> trust
# (It will ask you how much you trust them. Choose '5' for 'ultimate' if it's your key, or '3' for 'full' if you've personally verified it.)

gpg> quit
# (This saves your changes and exits)

Now you are ready to send them encrypted messages.

Clear Sign: Sign clear-text messages

Sometimes you don't need to hide a message, but you want to prove it came from you and wasn't changed. This is "signing". A "clear-signed" message leaves the text readable.

How to create it

# This creates a file 'cleartext.txt.asc'
gpg --clear-sign -u 9CF295D2 cleartext.txt
  • -u (or --local-user) specifies which of your secret keys to use for signing (in case you have more than one).

How to verify it

Save the signed message (including the -----BEGIN PGP SIGNED MESSAGE----- and -----BEGIN PGP SIGNATURE----- blocks) as signed_msg.txt and run:

❯ gpg --decrypt signed_msg.txt
You can fetch my latest public key from keyserver...
...
gpg: Signature made Wed 31 May 2023 11:43:18 AM CST
gpg:                using EDDSA key 739673C5A6C3797A12986FFF410C99D49CF295D2
gpg: Good signature from "jm33@jm33.me <jm33@jm33.me>" [ultimate]

The message gpg: Good signature tells you two things:

  1. The signature is valid and belongs to the key ...410C99D49CF295D2.
  2. The message content has not been tampered with since it was signed.

How does this work?

It's not "encrypting with the secret key," which is a common confusion. Here's what really happens:

  1. Hash: GPG creates a short, unique digital summary of your message (called a "hash", e.g., SHA256).
  2. Sign: GPG then uses your secret key to encrypt only that hash. This encrypted hash is your digital signature.
  3. Verify: When your recipient verifies the message:
  4. Their GPG client uses your public key to decrypt the signature, revealing the original hash you made.
  5. It then calculates its own hash of the message text it received.
  6. It compares the two hashes. If they match, the signature is "good".

Encrypt Data with PGP

Symmetric Encryption (Password-Only)

This is a simple way to encrypt a file with just a password. It doesn't use any keypairs. This is useful for encrypting a file for yourself or for someone you can securely share a password with.

# Encrypts 'data.bin' to 'data.bin.gpg'
# It will ask you to create a passphrase for this file
gpg -c data.bin

# Decrypts 'data.bin.gpg' to a new file
# It will ask for the passphrase you created
gpg -d data.bin.gpg > decrypted.bin

Asymmetric Encryption (To a Recipient)

This is the main use case. You encrypt a file so that only your recipient can open it.

# Encrypt 'msg.txt' for the recipient with fingerprint ...3E456E68
# AND sign it with your own key (...410C99D49CF295D2)
❯ gpg --encrypt --recipient 00416191C169BCF410712173E9FAF7E43E456E68 --sign -u 410C99D49CF295D2 msg.txt

This creates msg.txt.gpg.

  • --encrypt: Tells GPG to encrypt.
  • --recipient: Tells GPG who to encrypt for (using their public key).
  • --sign: Tells GPG to also sign the message with your secret key, so they know it's from you.
  • -u: (or --local-user) Specifies your secret key to use for the signature.

Pro-tip: When you encrypt a file, you are encrypting it for someone else's public key. This means even you can't decrypt it unless you also add yourself as a recipient.

# To encrypt for a recipient AND for yourself:
gpg --encrypt --recipient RECIPIENT_ID --recipient-self --sign -u YOUR_KEY_ID msg.txt
  • --recipient-self is a handy shortcut to add your own key from the -u flag as a recipient.

To decrypt and verify: The recipient just needs to run:

❯ gpg --decrypt msg.txt.gpg
...
(The original message content is displayed)
...
gpg: Signature made Sun 04 Jun 2023 07:42:23 PM CST
gpg:                using EDDSA key 739673C5A6C3797A12986FFF410C99D49CF295D2
gpg: Good signature from "jm33@jm33.me <jm33@jm33.me>" [ultimate]

GPG automatically uses their secret key to decrypt the file and verifies the signature with your public key.

Thunderbird and PGP

The Thunderbird email client has excellent, built-in OpenPGP support.

First, you need to export your secret key from GPG on your command line so you can import it into Thunderbird.

# Export your secret key (identified by its fingerprint or email) to a file
gpg --export-secret-keys -a 00416191C169BCF410712173E9FAF7E43E456E68 > my-secret-key.asc

Treat this my-secret-key.asc file as securely as a password!

Now, in Thunderbird:

  1. Assuming you have already configured your email account, click the menu button.
  2. Go to Account Settings.
  3. Select your email account from the left-hand menu.
  4. Click on End-to-End Encryption.
  5. Under the "OpenPGP" section, click Add Key....
  6. Choose Import an existing OpenPGP Key and click Continue.
  7. Select the my-secret-key.asc file you just exported.
  8. Thunderbird will ask for the passphrase you created when you generated the key.
  9. After importing, you must select the key to actively use with your account. While still in the End-to-End Encryption settings, select your newly imported key under "Use this OpenPGP key for this account".

Now, when you compose a new email, you will see an "Encryption" or "Security" button where you can choose to sign and/or encrypt the message. Thunderbird will automatically fetch the public keys of your recipients if they are on a keyserver or attached to an email you received from them.

Example: Sending an Encrypted Email to Me (jm33@jm33.me)

Here is my own PGP key information, which I've signed to prove it's authentic. You can find this block at https://jm33.me/pages/gpg.html.

Let's use this as a real-world example to tie everything together.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

You can fetch my public key from Ubuntu key server:

    gpg --keyserver hkps://keyserver.ubuntu.com --recv-key 5BEF5813ACA297CEA6F74C32FD7899D296E6FCE2

To verify:

    gpg --fingerprint 5BEF5813ACA297CEA6F74C32FD7899D296E6FCE2

You should see:

    pub   ed25519 2025-09-21 [SC] [expires: 2028-09-21]
          5BEF 5813 ACA2 97CE A6F7  4C32 FD78 99D2 96E6 FCE2
    uid           [  full  ] Jimmy Mi <jm33@jm33.me>
    sub   cv25519 2025-09-21 [E] [expires: 2028-09-21]

The following keys are also in use:

    ProtonMail key
    739673C5A6C3797A12986FFF410C99D49CF295D2

    Git commits
    A914BB005F8A42F36C2997594876EC6D60BDB1DF
    6D15BC0F5325CFD19E54568E8F97F3B56FB4E276

You can fetch them using gpg with the same command above, just replace the key fingerprint.

Use ProtonMail key for emails, if you have concerns, encrypt with 5BEF5813ACA297CEA6F74C32FD7899D296E6FCE2.

Sign my key to trust it:

    gpg --sign-key 5BEF5813ACA297CEA6F74C32FD7899D296E6FCE2

To upload the signed key to Ubuntu key server:

    gpg --keyserver hkps://keyserver.ubuntu.com --send-key 5BEF5813ACA297CEA6F74C32FD7899D296E6FCE2

Thanks in advance if you decide to sign my key!
-----BEGIN PGP SIGNATURE-----

iHUEARYKAB0WIQRb71gTrKKXzqb3TDL9eJnSlub84gUCaM9z1AAKCRD9eJnSlub8
4ptvAQDGtjM89OF2/eWcG33uF1Xd+8/B7ZGtZW1niAyosAuD/AEAj3Z03wIGNHCu
ipG9AZU/ZSTmhICZYqByOBQwlkHPjAA=
=lOHt
-----END PGP SIGNATURE-----

So, how would you use this to send me an encrypted email? Here's the step-by-step process:

Step 1. Verify the Message (Optional, but good practice)

First, you can verify that this message block itself is authentic. Save the entire block above to a file named jimmy_key.txt. Then run:

gpg --decrypt jimmy_key.txt

If you have already imported my key (5BEF...FCE2), GPG will check the signature and report gpg: Good signature from "Jimmy Mi <jm33@jm33.me>". This proves the instructions weren't tampered with.

Step 2. Get My Public Key for Email

The instructions say: "Use ProtonMail key for emails". This is the key I prefer for email correspondence.

The fingerprint for that key is: 7396...95D2.

Let's import this key from the keyserver:

gpg --keyserver hkps://keyserver.ubuntu.com --recv-key 739673C5A6C3797A12986FFF410C99D49CF295D2

Step 3. Verify and Trust My Key

Now that you have the key, you must verify it (as described in the "Obtain and Trust" section).

gpg --fingerprint 739673C5A6C3797A12986FFF410C99D49CF295D2

You would check this fingerprint against a trusted source (like my GitHub or Twitter bio). Once you're sure it's me, sign my key to tell your GPG you trust it:

# Start the key editor
gpg --edit-key 739673C5A6C3797A12986FFF410C99D49CF295D2

# In the GPG prompt:
gpg> sign   # Sign the key
gpg> trust  # Set trust level (e.g., '3' for 'full')
gpg> quit   # Save and quit

Step 4. Write and Encrypt Your Email

Now you're ready!

  1. Write your message in a plain text file, let's call it my_secret_message.txt.

bash echo "Hello Jimmy, this is a secret message just for you." > my_secret_message.txt

  1. Encrypt it for me (using my key) and sign it (using your key) so I know it's from you.

bash # Replace 'YOUR_KEY_FINGERPRINT' with your own key's fingerprint or email gpg --encrypt --recipient 739673C5A6C3797A12986FFF410C99D49CF295D2 \ --sign --local-user 'YOUR_KEY_FINGERPRINT' \ my_secret_message.txt

This creates my_secret_message.txt.gpg. This .gpg file is what you attach to an email and send to me at jm33@jm33.me. Only I will be able to decrypt it.

If you're using Thunderbird, this process is even easier. After importing my key, just click the "Encrypt" button before sending your email, and Thunderbird will handle all this for you.


Comments

comments powered by Disqus