Encrypt and Decrypt Files with GPG in Linux

CompTIABeginner
Practice Now

Introduction

In this lab, you will learn the essential skills to encrypt and decrypt files in a Linux environment using GPG (GNU Privacy Guard). You will start by generating your own public/private key pair, the foundation of GPG's security model. Following key generation, you will practice the core operations of encrypting a file for yourself and then decrypting it using your secret key and passphrase.

Building on these fundamentals, you will explore how to securely exchange information with others. This includes exporting your public key to share it and importing another user's public key. You will also learn how to sign a public key to verify its authenticity and perform crucial key maintenance tasks, such as backing up your secret key and creating a revocation certificate in case your key is ever compromised.

Generate Your GPG Key Pair with gpg --gen-key

In this step, you will generate your personal GPG (GNU Privacy Guard) key pair. A GPG key pair consists of two distinct but related keys: a public key and a private key. You can share your public key with others so they can encrypt files for you. You must keep your private key secret, as it is the only key that can decrypt files encrypted with your public key.

First, let's ensure that the gnupg package, which provides the GPG functionality, is installed on your system.

sudo apt-get update && sudo apt-get install -y gnupg

Now, you are ready to generate your key pair. The gpg --gen-key command will guide you through an interactive process.

Execute the following command in your terminal:

gpg --gen-key

You will see a note that this command uses simplified key generation. For more advanced options, you can use gpg --full-generate-key, but the default options are suitable for this lab.

You will be prompted for the following information:

  1. Real name: Enter labex
  2. Email address: Enter labex@example.com
  3. Confirm User ID: Review your details. When prompted Change (N)ame, (E)mail, or (O)kay/(Q)uit?, type O and press Enter.

The system will automatically use secure defaults:

  • Key type: RSA and RSA (default)
  • Key size: 3072 bits (secure default)
  • Key validity: 2 years (automatic expiration for security)

Note: Unlike older versions, modern GPG may not prompt for a passphrase during key generation using --gen-key. If you want to add a passphrase to your key for additional security, you can do so later using:

gpg --edit-key labex

Then type passwd at the GPG prompt to set a passphrase, followed by save to exit.

The system will now generate your key pair. This process requires random data (entropy) and may take a few moments.

Once completed, you will see a confirmation message similar to this:

gpg: key <KEY_ID> marked as ultimately trusted
gpg: revocation certificate stored as '/home/labex/.gnupg/openpgp-revocs.d/<FINGERPRINT>.rev'
public and secret key created and signed.

pub   rsa3072 2025-07-01 [SC] [expires: 2027-07-01]
      <FINGERPRINT>
uid                      labex <labex@example.com>
sub   rsa3072 2025-07-01 [E] [expires: 2027-07-01]

Now that your keys are generated, you can view them. To see your new public key, run:

gpg --list-keys

The output will list all public keys in your keyring, including the one you just created:

/home/labex/.gnupg/pubring.kbx
------------------------------
pub   rsa3072 2025-07-01 [SC] [expires: 2027-07-01]
      <FINGERPRINT>
uid           [ultimate] labex <labex@example.com>
sub   rsa3072 2025-07-01 [E] [expires: 2027-07-01]

To view your private key, run:

gpg --list-secret-keys

The output will be similar, but it indicates a secret key (sec) instead of a public key (pub):

/home/labex/.gnupg/pubring.kbx
------------------------------
sec   rsa3072 2025-07-01 [SC] [expires: 2027-07-01]
      <FINGERPRINT>
uid           [ultimate] labex <labex@example.com>
ssb   rsa3072 2025-07-01 [E] [expires: 2027-07-01]

You have now successfully created and verified your GPG key pair.

Encrypt and Decrypt a Local File with gpg -e and gpg --decrypt

In this step, you will use the GPG key pair you generated to encrypt and then decrypt a file. This is a fundamental use case for GPG, allowing you to protect the confidentiality of your data. Encryption transforms your readable data into an unreadable format, and only someone with the correct private key can decrypt it back to its original form.

First, let's create a simple text file to work with. All operations will be performed in your current directory, ~/project.

echo "This is a secret message for the lab." > mytestfile.txt

Now, you can encrypt this file using your public key. The gpg -e command is used for encryption. You also need to specify the recipient of the encrypted message with the -r flag, which should be the name associated with your GPG key (labex).

gpg -e -r labex mytestfile.txt

GPG will use your public key to encrypt the file. You will not be prompted for your passphrase because encryption is done with the public key, which is not secret.

After the command completes, use the ls command to see the new encrypted file.

ls

You should see mytestfile.txt.gpg in the output, alongside the original file.

mytestfile.txt  mytestfile.txt.gpg

The file mytestfile.txt.gpg contains the encrypted data. If you try to view its contents, you will see unreadable binary data.

Now, let's decrypt the file. To do this, you'll use the gpg --decrypt command. Since you are decrypting, GPG will use your private key.

We will use the --output flag to specify a new file for the decrypted content, mytestfile.txt.decrypted. This prevents overwriting the original file and makes it clear which file is which.

gpg --output mytestfile.txt.decrypted --decrypt mytestfile.txt.gpg

If your key has a passphrase, you will be prompted to enter it. If no passphrase was set during key generation, the decryption will proceed automatically. You should see output similar to:

gpg: encrypted with 3072-bit RSA key, ID <KEY_ID>, created 2025-07-01
      "labex <labex@example.com>"

Once decrypted, you can view the contents of the new file to confirm it matches the original message.

cat mytestfile.txt.decrypted

The output should be the original text you created:

This is a secret message for the lab.

You have successfully encrypted a file for yourself and then decrypted it using your GPG key pair.

Exchange Public Keys with gpg --export and gpg --import

In this step, you will learn how to exchange public keys with others. To encrypt a file for someone else, you need their public key. Similarly, if someone wants to send you an encrypted file, they need your public key. This process involves exporting your public key to a file and importing public keys you receive from others into your GPG keyring.

First, let's export your own public key. You will use the gpg --export command. It's best practice to use the --armor option, which creates a text-based (ASCII) version of the key, making it easy to copy and paste into emails or other text-based communication channels. We'll save it to a file named labex.pub.

In your terminal, run the following command. Replace labex with the user ID you used during key generation.

gpg --export --armor -o labex.pub labex

You can verify that the file was created using ls:

ls

You should see labex.pub in the file list. You can also view its contents:

cat labex.pub

The output will be a block of text starting with -----BEGIN PGP PUBLIC KEY BLOCK-----. This is your public key, which you can now share with others.

Next, you will simulate receiving a public key from another user and importing it into your keyring. In a real scenario, you would receive the public key from another person through a secure channel. For this lab, we'll create a temporary Alice key pair and then export Alice's public key to simulate this process.

First, let's temporarily generate a key pair for Alice. We'll use a batch mode to automate this process without interactive prompts:

cat > alice-key-params << 'EOF'
Key-Type: RSA
Key-Length: 2048
Subkey-Type: RSA
Subkey-Length: 2048
Name-Real: Alice
Name-Email: alice@example.com
Expire-Date: 2y
%no-protection
%commit
EOF

Now generate Alice's key pair using the parameters file:

gpg --batch --generate-key alice-key-params

You should see output confirming the key generation:

gpg: key <KEY_ID> marked as ultimately trusted
public and secret key created and signed.

Now export Alice's public key to a file, simulating how you would receive it from Alice:

gpg --export --armor -o alice.pub alice@example.com

For this lab demonstration, we'll also remove Alice's secret key from the keyring since in reality you would only have her public key:

gpg --delete-secret-keys alice@example.com

When prompted, confirm the deletion by typing y and pressing Enter.

gpg --delete-keys alice@example.com

Again, confirm the deletion by typing y and pressing Enter.

Now you have Alice's public key in the file alice.pub, simulating how you would receive it from another user.

Clean up the temporary key generation file:

rm alice-key-params

Now that you have Alice's public key in a file, import it into your GPG keyring using the gpg --import command.

gpg --import alice.pub

You should see output confirming the key was imported:

gpg: key <KEY_ID>: public key "Alice <alice@example.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1

To confirm that Alice's key is now in your keyring, list all your public keys again.

gpg --list-keys

The output will now show both your key (labex) and the newly imported key (Alice).

/home/labex/.gnupg/pubring.kbx
------------------------------
pub   rsa3072 2025-07-01 [SC] [expires: 2027-07-01]
      <FINGERPRINT_LABEX>
uid           [ultimate] labex <labex@example.com>
sub   rsa3072 2025-07-01 [E] [expires: 2027-07-01]

pub   rsa2048 2025-07-01 [SC] [expires: 2027-07-01]
      <FINGERPRINT_ALICE>
uid           [ unknown] Alice <alice@example.com>
sub   rsa2048 2025-07-01 [E] [expires: 2027-07-01]

Notice that Alice's key is marked with [ unknown] trust. You'll learn how to manage key trust in the next step.

Sign a Public Key and Encrypt a File for Another User

In this step, you will learn how to establish trust in a public key you've received and then use it to encrypt a file for its owner. When you import a public key, GPG has no way of knowing if it's authentic. By "signing" the key with your own private key, you are creating a cryptographic endorsement, essentially telling your GPG setup, "I trust that this key belongs to this person." This is a fundamental concept in GPG's "Web of Trust" model.

First, you need to sign the public key for "Alice" that you imported in the previous step. You will use the gpg --sign-key command, identifying the key by its email address (alice@example.com).

gpg --sign-key alice@example.com

GPG will display the details of Alice's key and ask you to confirm that you want to sign it.

pub  rsa2048/XXXXXXXXXXXXXXXX 2025-07-01
     created: 2025-07-01  expires: 2027-07-01  usage: SC
     trust: unknown       validity: unknown
sub  rsa2048/YYYYYYYYYYYYYYYY 2025-07-01
     created: 2025-07-01  expires: 2027-07-01  usage: E
[ unknown] (1). Alice <alice@example.com>

Really sign? (y/N)

Type y and press Enter. If your key has a passphrase, you will be prompted to enter it. This is because a signature is a cryptographic operation that can only be performed with your secret key. Enter your passphrase if prompted and press Enter.

Once done, you can verify the signature by listing the keys again.

gpg --list-keys

Notice the change in the entry for Alice's key. The trust level is no longer [unknown]. It now shows [ultimate] because you have explicitly trusted it by signing it.

/home/labex/.gnupg/pubring.kbx
------------------------------
pub   rsa3072 2025-07-01 [SC] [expires: 2027-07-01]
      <FINGERPRINT_LABEX>
uid           [ultimate] labex <labex@example.com>
sub   rsa3072 2025-07-01 [E] [expires: 2027-07-01]

pub   rsa2048 2025-07-01 [SC] [expires: 2027-07-01]
      <FINGERPRINT_ALICE>
uid           [ultimate] Alice <alice@example.com>
sub   rsa2048 2025-07-01 [E] [expires: 2027-07-01]

Now that you have a trusted public key for Alice, you can encrypt a file that only she can open. First, create a new file for this purpose.

echo "This is a confidential message for Alice." > message-for-alice.txt

Next, encrypt this file using the gpg -e command. This time, specify Alice as the recipient with the -r flag.

gpg -e -r alice@example.com message-for-alice.txt

GPG will use Alice's public key to perform the encryption. Use ls to see the result.

ls

You will see the new encrypted file, message-for-alice.txt.gpg, in your directory.

labex.pub                 mytestfile.txt
alice.pub                 mytestfile.txt.decrypted
message-for-alice.txt     mytestfile.txt.gpg
message-for-alice.txt.gpg

This file is now securely encrypted. Only someone with access to Alice's private key (and its passphrase) can decrypt and read the message.

Perform Key Maintenance with gpg --export-secret-keys and gpg --gen-revoke

In this final step, you will perform two critical maintenance tasks for your GPG key: creating a secure backup of your secret key and generating a revocation certificate. Your secret key is irreplaceable; if you lose it, you lose access to all data encrypted with the corresponding public key. A revocation certificate is your safety net, allowing you to invalidate your public key if your secret key is ever lost or compromised.

First, let's create a backup of your secret key. This is one of the most important steps in managing a GPG key.

The command gpg --export-secret-keys is used for this purpose. We will use the --armor flag to create an ASCII-armored text file, which is easy to store and transport. You must specify which key to export by its user ID.

gpg --export-secret-keys --armor -o gpgkey.asc labex

This command exports the secret key for the user labex into a file named gpgkey.asc. This file is extremely sensitive. In a real-world scenario, you would store this file in a very secure, offline location, such as an encrypted USB drive or a secure vault.

Next, you will create a revocation certificate. This should be done immediately after key generation and stored securely, separate from your secret key backup. If you lose your secret key or it gets stolen, you can publish this certificate to let others know that the key should no longer be used or trusted.

Use the gpg --gen-revoke command. We will save the certificate to a file named revoke.asc using the --output flag.

gpg --output revoke.asc --gen-revoke labex

You will be guided through an interactive process:

  1. When asked Create a revocation certificate for this key? (y/N), type y and press Enter.
  2. You will be prompted to select a reason for the revocation. For this lab, press Enter to accept the default 0 = No reason specified.
  3. You can add an optional description. For now, just press Enter to leave it blank.
  4. Finally, confirm the details by typing y and pressing Enter when asked Is this okay? (y/N).
  5. If your key has a passphrase, GPG will ask for it to authorize the creation of this certificate. Enter your passphrase if prompted and press Enter.

You will see a confirmation that the revocation certificate has been created.

Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable.  But have some caution:  The printout
might be scanned and reconstructed by a determined attacker.

Use the ls command to verify that both new files have been created in your ~/project directory.

ls

You should now see gpgkey.asc and revoke.asc in the file listing. You have successfully performed essential key maintenance.

Summary

In this lab, you learned the fundamental operations of GNU Privacy Guard (GPG) in a Linux environment. You started by generating a personal GPG key pair, consisting of a public and a private key, using the gpg --gen-key command. This process involved selecting key specifications and creating a user ID protected by a secure passphrase. Following the key generation, you practiced the core function of GPG by encrypting a local file for yourself with gpg -e and subsequently decrypting it using your private key and the gpg --decrypt command, demonstrating the basic principles of asymmetric encryption.

Building on these basics, you explored how to securely communicate with others. You learned to exchange public keys using gpg --export to share your key and gpg --import to receive another user's key. The lab also covered the importance of establishing trust by signing an imported public key and then using it to encrypt a file specifically for that user. Finally, you performed essential key maintenance tasks, including backing up your secret key with gpg --export-secret-keys and creating a revocation certificate using gpg --gen-revoke to invalidate your key pair if it becomes compromised.