Salta ai contenuti

PGP/GPG

PGP (Pretty Good Privacy) and GPG (GnuPG) enable encrypted communication and file signing using public-key cryptography.

Installation

macOS

# Homebrew
brew install gnupg

# Homebrew GUI
brew install gpg-suite

Linux

# Debian/Ubuntu
sudo apt-get install gnupg gnupg2

# RHEL/CentOS/Fedora
sudo dnf install gnupg gnupg2

# Arch
sudo pacman -S gnupg

Windows

# Chocolatey
choco install gnupg

# Scoop
scoop install gpg

# GUI
https://www.gpg4win.org/

Key Generation

Generate New Key Pair

# Interactive key generation
gpg --full-generate-key

# Batch generation
gpg --batch --generate-key << EOF
%pubring keyring.pub
%secring keyring.sec
Key-Type: RSA
Key-Length: 4096
Name-Real: John Doe
Name-Email: john@example.com
Expire-Date: 2y
%commit
EOF

# Quick generation (default settings)
gpg --quick-generate-key "John Doe <john@example.com>" rsa4096 cert 2y

Key Parameters

# Default: RSA 3072-bit
# Recommended: RSA 4096-bit or Ed25519

# Generate with EdDSA (faster, modern)
gpg --quick-generate-key "Name <email>" ed25519 cert 2y

# Generate with specific capabilities
gpg --quick-generate-key "Name <email>" rsa4096 encr,sign 1y

Key Management

List Keys

# List public keys
gpg --list-keys

# List public keys detailed
gpg --list-sigs

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

# List specific key
gpg --list-keys FINGERPRINT

# Show fingerprint
gpg --fingerprint EMAIL@example.com

# Export key info
gpg --export-options export-minimal --export EMAIL@example.com

Edit Key

# Interactive key editing
gpg --edit-key FINGERPRINT

# Commands in edit mode:
# addkey        - Add subkey
# adduid        - Add user ID
# delkey        - Delete subkey
# delsig        - Delete signature
# trust         - Set trust level
# expire        - Set key expiration
# sign          - Sign another key
# save          - Save changes

# Example: Add encryption subkey
gpg --edit-key EMAIL@example.com << EOF
addkey
10  # RSA (sign only)
4096
2y
save
EOF

Change Passphrase

# Change passphrase interactively
gpg --edit-key FINGERPRINT
# Then: passwd

# Non-interactive change (requires expect)
expect -c "
spawn gpg --edit-key FINGERPRINT
expect \"gpg> \"
send \"passwd\n\"
expect \"Enter passphrase:\"
send \"oldpass\n\"
expect \"New passphrase:\"
send \"newpass\n\"
expect \"Repeat passphrase:\"
send \"newpass\n\"
expect \"gpg> \"
send \"quit\n\"
"

Revoke Key

# Generate revocation certificate
gpg --output revoke.asc --gen-revoke FINGERPRINT

# Revoke key using certificate
gpg --import revoke.asc

# Or directly revoke (if you have the key)
gpg --edit-key FINGERPRINT
# Then: revkey, save

Encryption and Decryption

Encrypt File

# Encrypt for single recipient
gpg --encrypt --recipient EMAIL@example.com file.txt
# Creates: file.txt.gpg

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

# Encrypt without compression
gpg --encrypt --no-compress --recipient EMAIL file.txt

# Symmetric encryption (password-only)
gpg --symmetric file.txt
# Enter passphrase (no public key needed)

# ASCII armor output (portable text)
gpg --armor --encrypt --recipient EMAIL file.txt
# Creates: file.txt.asc

Decrypt File

# Decrypt file
gpg --decrypt file.txt.gpg > file.txt

# Decrypt in-place
gpg --output file.txt --decrypt file.txt.gpg

# Decrypt without output (verify only)
gpg --decrypt file.txt.gpg

# Batch decrypt multiple files
for file in *.gpg; do
  gpg --output "${file%.gpg}" --decrypt "$file"
done

# Decrypt without passphrase prompt (agent)
# Requires: gpg-agent running with cached passphrase
gpg --batch --quiet --decrypt file.txt.gpg

Signing and Verification

Sign File

# Detached signature (recommended)
gpg --detach-sign file.txt
# Creates: file.txt.sig

# Signature in ASCII armor
gpg --detach-sign --armor file.txt
# Creates: file.txt.asc

# Clearsign (signature inside file)
gpg --clearsign file.txt
# Creates: file.txt.asc (text readable with signature)

# Sign and encrypt
gpg --sign --encrypt --recipient EMAIL file.txt
# Creates: file.txt.gpg (signed and encrypted)

# Batch sign files
for file in *.txt; do
  gpg --detach-sign "$file"
done

Verify Signature

# Verify detached signature
gpg --verify file.txt.sig file.txt

# Verify clearsigned file
gpg --verify file.txt.asc

# Batch verify
for file in *.sig; do
  gpg --verify "$file" "${file%.sig}"
done

# Get verification details
gpg --verify file.txt.sig file.txt 2>&1 | grep -E "(Good|Bad|signature)"

Keyserver Operations

Search Keyserver

# Search on keys.openpgp.org (modern default)
gpg --search-keys EMAIL@example.com

# Search on specific keyserver
gpg --keyserver keyserver.ubuntu.com --search-keys EMAIL

# Other keyservers:
# keys.openpgp.org      (privacy-focused)
# keyserver.ubuntu.com  (popular)
# pgp.key-server.io     (full sync)
# keys.mailvelope.com   (web-friendly)

Import Key from Keyserver

# Import from default keyserver
gpg --auto-key-locate keyserver --locate-keys EMAIL@example.com

# Import from specific keyserver
gpg --keyserver keyserver.ubuntu.com --recv-keys FINGERPRINT

# Import multiple keys
gpg --recv-keys KEY1 KEY2 KEY3

# Refresh keys
gpg --refresh-keys

# Import from file
gpg --import keyfile.asc

Export and Upload Keys

# Export public key to file
gpg --export --armor EMAIL@example.com > public.asc

# Export secret key (CAUTION)
gpg --export-secret-keys --armor EMAIL > secret.asc
# Secure this file!

# Export minimal key
gpg --export-options export-minimal --armor --export EMAIL > minimal.asc

# Upload to keyserver
gpg --send-keys FINGERPRINT

# Upload to specific keyserver
gpg --keyserver keyserver.ubuntu.com --send-keys FINGERPRINT

Trust and Signing

Set Trust Level

# Interactive trust settings
gpg --edit-key EMAIL@example.com
# Then: trust

# Levels:
# 1 = I do not know or I do not want to say how much I trust
# 2 = I do NOT trust
# 3 = I trust marginally
# 4 = I trust fully
# 5 = I trust ultimately

# Set trust in batch mode
echo "EMAIL@example.com:4:" | gpg --import-ownertrust

Sign Other Keys

# Sign another user's key
gpg --sign-key EMAIL@example.com

# Local signature (not exportable)
gpg --lsign-key EMAIL@example.com

# Sign with specific key
gpg --default-key YOUR-KEY --sign-key OTHER-KEY

# Export signed key
gpg --export --armor EMAIL@example.com > signed.asc

Advanced Operations

Export/Import Keys

# Export all public keys
gpg --export --armor > all-public.asc

# Export all secret keys (SECURE THIS!)
gpg --export-secret-keys --armor > all-secret.asc

# Import keys
gpg --import keys.asc

# Backup entire keyring
tar czf keyring-backup.tar.gz ~/.gnupg/

Key Statistics

# Count keys
gpg --list-keys | grep "^pub" | wc -l

# Find expired keys
gpg --list-keys | grep expired

# Find keys without signatures
gpg --list-sigs | grep -v "^sig"

# Show key usage dates
gpg --list-keys --with-subkey-fingerprint EMAIL

Password Manager Integration

# Export key for backup into password manager
gpg --export-secret-keys --armor EMAIL@example.com

# Store in password manager (secure)
# Keep offline backup encrypted with strong password

Scripting Examples

Batch Encryption

#!/bin/bash
# Encrypt multiple files for recipient

RECIPIENT="alice@example.com"
FILES=$(find . -type f -name "*.txt")

for file in $FILES; do
    echo "Encrypting $file..."
    gpg --encrypt --recipient "$RECIPIENT" --armor "$file"
    echo "Created ${file}.asc"
done

Decrypt and Process

#!/bin/bash
# Decrypt and process encrypted config

CONFIG_FILE="config.txt.gpg"
TEMP_FILE=$(mktemp)

# Decrypt to temporary file
gpg --output "$TEMP_FILE" --decrypt "$CONFIG_FILE"

# Source configuration
source "$TEMP_FILE"

# Use configuration
echo "Database: $DB_HOST"
echo "User: $DB_USER"

# Securely delete temporary file
shred -vfz -n 3 "$TEMP_FILE"

Email Integration

#!/bin/bash
# Encrypt and email sensitive file

RECIPIENT="recipient@example.com"
FILE="sensitive.txt"
EMAIL_SUBJECT="Encrypted document"

# Encrypt file
gpg --encrypt --recipient "$RECIPIENT" --armor "$FILE"

# Email encrypted file
echo "See attached encrypted file." | \
mail -s "$EMAIL_SUBJECT" \
     -a "${FILE}.asc" \
     "$RECIPIENT"

Troubleshooting

Common Issues

Issue: “gpg: decryption failed: No secret key”

# Verify you have the private key
gpg --list-secret-keys

# Import your private key if missing
gpg --import private-key.asc

# Check key permissions
ls -la ~/.gnupg/private-keys-v1.d/

Issue: “sign_and_send_pubkey: signing failed”

# Agent issue; restart agent
gpgconf --kill gpg-agent
gpg-agent --daemon

# Provide passphrase
gpg --clearsign file.txt
# (Requires manual passphrase entry)

Issue: “keyserver connection failed”

# Try different keyserver
gpg --keyserver keys.openpgp.org --search-keys email@example.com

# Check network connectivity
ping keyserver.ubuntu.com

# Proxy configuration
gpg --keyserver-options http-proxy=http://proxy:port --search-keys email

Issue: “untrusted key”

# Trust the key
gpg --edit-key KEY-ID
# Then: trust, 4 (I trust fully), quit

# Or set as ultimately trusted
echo "KEY-ID:6:" | gpg --import-ownertrust

Security Best Practices

  • Store private keys securely (encrypted backup)
  • Use strong passphrases (15+ characters)
  • Keep GPG software updated
  • Verify key fingerprints before signing
  • Trust keys carefully (don’t trust everyone)
  • Use subkeys for daily encryption/signing
  • Keep master key offline if possible
  • Regularly rotate passphrases
  • Backup revocation certificates
  • Audit key signatures periodically

Last updated: 2026-03-30