GPG Encryption

GPG cheatsheet — generate keys, encrypt/decrypt files, sign and verify. gpg --gen-key, gpg -e -r email file, gpg -d file.gpg, gpg --sign, gpg --verify. Full GPG reference.

9 min read

What it is

GPG (GNU Privacy Guard) is a free and open-source implementation of the OpenPGP standard used for encrypting and signing data and communications.

Installation

Linux

sudo apt update && sudo apt install gnupg
# Or on Fedora/CentOS/RHEL
sudo dnf install gnupg

macOS

brew install gnupg

Windows

Download and install from the GPG4win installer: https://www.gpg4win.org/

Core Concepts

  • Public Key: A key that can be shared freely. Used to encrypt messages to someone and to verify signatures from someone.
  • Secret Key: A private key that must be kept secret. Used to decrypt messages encrypted with your public key and to create signatures.
  • Key Pair: A public key and its corresponding secret key.
  • Passphrase: A password used to protect your secret key.
  • Trust Model: GPG uses a web of trust model. You can explicitly trust keys, or trust them based on others you trust.
  • Key ID: A unique identifier for a GPG key. Often the last 8 or 16 hexadecimal characters of the key’s fingerprint.
  • Fingerprint: A long, unique string representing the entire public key. Used for unambiguous identification.

Commands / Usage

Key Management

Generating a New Key Pair

gpg --full-generate-key

This command prompts you through generating a new RSA and RSA key pair. You’ll choose key type, key size, expiration date, and provide your real name, email address, and a secure passphrase.

Listing Keys

# List public keys
gpg --list-keys

# List secret keys
gpg --list-secret-keys

These commands display your public and secret keyrings, showing key IDs, owner information, and expiration dates.

Exporting a Public Key

# Export to stdout
gpg --armor --export alice@example.com

# Export to a file
gpg --armor --export alice@example.com > alice_pubkey.asc

Exports the public key associated with alice@example.com in ASCII-armored format, making it easy to share.

Exporting a Secret Key (Use with extreme caution!)

# Export to stdout
gpg --armor --export-secret-key alice@example.com

# Export to a file
gpg --armor --export-secret-key alice@example.com > alice_secretkey.asc

Exports your secret key. This is highly sensitive. Protect this file and its passphrase.

Importing a Public Key

# Import from stdin
gpg --import
# Then paste the key content and press Ctrl+D

# Import from a file
gpg --import bob_pubkey.asc

Imports a public key from bob_pubkey.asc into your keyring. This allows you to encrypt messages to Bob and verify his signatures.

Importing a Secret Key (Use with extreme caution!)

# Import from stdin
gpg --import
# Then paste the secret key content and press Ctrl+D

# Import from a file
gpg --import alice_secretkey.asc

Imports a secret key. You will be prompted for the passphrase protecting it.

Deleting a Key

# Delete a public key
gpg --delete-key alice@example.com

# Delete a secret key
gpg --delete-secret-key alice@example.com

Removes the specified key from your keyring.

Revoking a Key

# Generate a revocation certificate
gpg --output revoke_alice.asc --gen-revoke alice@example.com

# Then upload it (e.g., to a keyserver)
gpg --keyserver hkps://keys.openpgp.org --send-keys alice@example.com

Generates a certificate to revoke your key, invalidating it. You should then upload this certificate to keyservers.

Trusting Keys

# List keys with trust levels
gpg --list-trust

# Set trust level for a key (e.g., completely trust Bob's key)
gpg --edit-key bob@example.com
# Then type 'trust' and select option '5' (I trust fully)

Manages the trust you place in other users’ keys.

Encryption and Decryption

Encrypting a File for a Recipient

# Encrypt 'message.txt' for 'alice@example.com'
gpg --encrypt --recipient alice@example.com message.txt

# Output to stdout (e.g., for piping)
gpg --encrypt --recipient alice@example.com --armor message.txt > message.asc

# Encrypt for multiple recipients
gpg --encrypt --recipient alice@example.com --recipient bob@example.com message.txt

Creates an encrypted file (message.txt.gpg by default) that only alice@example.com (using her public key) can decrypt.

Decrypting a File

# Decrypt 'message.txt.gpg' to 'message.txt'
gpg --decrypt message.txt.gpg > message.txt

# Decrypt an ASCII-armored file to stdout
gpg --decrypt message.asc > message.txt

Uses your secret key to decrypt the file. You will be prompted for your passphrase if your secret key is protected.

Encrypting and Signing (Detached Signature)

# Sign and encrypt 'document.txt' for 'alice@example.com'
gpg --sign --encrypt --recipient alice@example.com document.txt

Creates an encrypted file (document.txt.gpg) that is also signed by you. Alice can verify your signature after decrypting.

Encrypting and Signing (Clear-Signed Text)

# Clear-sign 'plaintext_message.txt'
gpg --clearsign plaintext_message.txt

Creates an ASCII-armored file (plaintext_message.txt.asc) containing the original text and a signature embedded within it. This is useful for human-readable signed messages.

Signing a File (Detached Signature)

# Sign 'data.tar.gz'
gpg --detach-sign data.tar.gz

# Sign and create an ASCII-armored signature
gpg --armor --detach-sign data.tar.gz

Creates a signature file (data.tar.gz.sig or data.tar.gz.asc) that can be verified against the original data.tar.gz.

Verifying a Signature

# Verify a detached signature file 'message.asc' against 'message.txt'
gpg --verify message.asc message.txt

# Verify an ASCII-armored signature file (often combined with decryption)
gpg --verify message.asc

Checks if the signature is valid and matches the content.

Verifying and Decrypting

# Verify and decrypt 'encrypted_signed_message.gpg'
gpg --decrypt encrypted_signed_message.gpg > decrypted_message.txt

When you decrypt a message that was also signed, GPG automatically verifies the signature during the decryption process.

Symmetric Encryption (Password-Based)

Encrypting with a Passphrase

# Encrypt 'secret_data.txt' using only a passphrase
gpg --symmetric secret_data.txt

# Encrypt to stdout in ASCII-armored format
gpg --symmetric --armor secret_data.txt > secret_data.asc

Encrypts secret_data.txt using a passphrase you provide. No keys are involved; only the passphrase is needed for decryption.

Decrypting with a Passphrase

# Decrypt 'secret_data.txt.gpg' using the passphrase
gpg --decrypt secret_data.txt.gpg > decrypted_data.txt

# Decrypt ASCII-armored file to stdout
gpg --decrypt secret_data.asc > decrypted_data.txt

Prompts for the passphrase used during encryption.

Key Servers

Searching for Keys

# Search keyservers for keys matching "Alice Example"
gpg --keyserver hkps://keys.openpgp.org --search-keys "Alice Example"

# Search keyservers for a specific email address
gpg --keyserver hkps://keys.openpgp.org --search-keys alice@example.com

Queries public keyservers for matching public keys.

Uploading Keys to a Keyserver

# Upload your public key
gpg --keyserver hkps://keys.openpgp.org --send-keys alice@example.com

# Upload a revocation certificate
gpg --keyserver hkps://keys.openpgp.org --send-keys alice@example.com

Publishes your public key (or revocation certificate) to a keyserver, making it discoverable by others.

Fetching Keys from a Keyserver

# Fetch keys for 'bob@example.com' from the default keyserver
gpg --recv-keys bob@example.com

# Fetch keys for a specific key ID
gpg --recv-keys 0xDEADBEEFCAFEBABE

Downloads public keys from a keyserver into your local keyring.

Miscellaneous

Editing Key Information

gpg --edit-key alice@example.com

Enters an interactive mode to edit key attributes like expiration date, user ID, or trust level.

Exporting All Public Keys

gpg --export --armor > my_public_keys.asc

Exports all public keys in your local keyring to a single ASCII-armored file.

Importing All Public Keys

gpg --import all_public_keys.asc

Imports all public keys contained within the specified file.

Common Patterns

Encrypting a file for yourself and signing it

gpg --sign --encrypt --recipient $(gpg --list-keys --format "%u" your_email@example.com | head -n 1) your_file.txt

Encrypts your_file.txt for your own email address (obtained dynamically) and signs it.

Creating a reproducible build artifact signature

tar -czf myproject-1.0.tar.gz src/ include/ Makefile
gpg --armor --detach-sign myproject-1.0.tar.gz
mv myproject-1.0.tar.gz.asc myproject-1.0.tar.gz.sig

Creates a tarball and then generates a detached, ASCII-armored signature for it.

Securely deleting sensitive files

gpg --output sensitive.txt.gpg --symmetric sensitive.txt
rm sensitive.txt # Standard deletion
shred -uz sensitive.txt # More secure deletion (Linux/macOS)

Encrypts the file symmetrically, then securely removes the original plaintext file.

Verifying a downloaded file and its signature

wget https://example.com/software.tar.gz
wget https://example.com/software.tar.gz.sig
gpg --verify software.tar.gz.sig software.tar.gz
# If verification is successful, then extract
tar -xzf software.tar.gz

Downloads a software archive and its signature, verifies the signature, and then extracts the archive if valid.

Piping data to GPG for encryption

echo "This is a secret message." | gpg --encrypt --recipient alice@example.com --armor > secret.asc

Takes standard input, encrypts it for Alice, and saves the ASCII-armored output to secret.asc.

Piping data from GPG for decryption

gpg --decrypt encrypted.gpg | less

Decrypts encrypted.gpg and pipes the plaintext output to the less pager.

Gotchas

  • Passphrase Strength: The security of your secret key relies entirely on the strength of its passphrase. Use a long, complex, and unique passphrase.
  • Secret Key Secrecy: Never share your secret key. If it’s compromised, your encrypted communications are no longer secure.
  • Key Expiration: Keys expire. Ensure you renew them or generate new ones before they do. Old keys might be rejected by some software.
  • Trust is Manual: GPG doesn’t automatically trust keys. You need to explicitly trust keys you intend to communicate with securely, or rely on a web of trust built by others.
  • ASCII Armor: --armor (or -a) is crucial when exchanging keys or encrypted messages via email or text-based systems, as it converts binary data into printable ASCII characters.
  • Key ID Ambiguity: Short Key IDs (like the last 8 hex digits) can sometimes collide. Always use the full fingerprint for absolute certainty when identifying keys, especially in critical operations.
  • Revocation Certificates: If you lose your secret key or passphrase, or if it’s compromised, you must generate and upload a revocation certificate to invalidate your key. Otherwise, others might continue to use an invalid key.
  • Keyserver Policies: Keyservers are public directories. Anything uploaded (keys, revocation certificates) is generally permanent and publicly accessible. Be mindful of what you upload.
  • --batch mode: When scripting, use --batch --yes to suppress interactive prompts, but be extremely careful as this can lead to accidental actions if not used correctly.