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.
--batchmode: When scripting, use--batch --yesto suppress interactive prompts, but be extremely careful as this can lead to accidental actions if not used correctly.