Introduction to GnuPG
I rely on Pretty Good Privacy (PGP) and its open implementation, GnuPG (GPG), to keep secure email, software distribution, and signed…
Introduction to GnuPG
I rely on Pretty Good Privacy (PGP) and its open implementation, GnuPG (GPG), to keep secure email, software distribution, and signed source code flowing safely. In this guide, I’ll show you exactly how I build trustworthy OpenPGP identities — from generating resilient key pairs to exchanging them over key servers, encrypting data, and signing releases. If you want practical GnuPG best practices for modern engineering workflows, you’re in the right place.
GPG Basics in One Paragraph
GPG implements the OpenPGP standard, so every identity begins as a key pair: a public key that you share freely and a private key that you guard closely. An OpenPGP key stores:
- Identity data: user IDs with names, email addresses, and trust levels, so collaborators can confirm who you are.
- Cryptographic core: the large integers, algorithms (RSA, ECC, Ed25519), creation dates, expiration timers, revocation status, and capability flags.
With that metadata, GPG can handle signing, encryption, subkeys, and trust workflows such as the web-of-trust, trust signatures, key servers, and the Web Key Directory (WKD).
Installation and Environment
Quick Setup Checklist
- Linux:
sudo apt install gnupgon Debian/Ubuntu orsudo dnf install gnupg2on Fedora/RHEL. - macOS:
brew install gnupg, which bundlesgpg-agentand the CLI tools. - Windows: Install Gpg4win for Kleopatra, along with the command-line binaries.
- Verify:
gpg --versionShows enabled algorithms and the default keyring path (typically~/.gnupg).
Generating a Strong Key
Before touching the keyboard, I map the identities I need: a certification-capable primary key and subkeys for signing, encryption, and authentication. Knowing why each subkey exists makes future rotations painless.
Interactive Generation
gpg --full-generate-key
During the prompts, I focus on:
- Key type: option
1(RSA and RSA) for compatibility or9(ECC and ECC) for Ed25519/X25519 on modern stacks. - Key length: RSA 3072-bit minimum; 4096-bit if I can trade a bit of performance for longevity.
- Expiration: set a renewal cadence so I revisit the key annually or every two years.
- User IDs:
Full Name <email@example.com>plus any alternate addresses I need. - Passphrase: long, unique, and stored via a password manager —
gpg-agenthandles caching.
Once the key is in ~/.gnupg/pubring.kbx and ~/.gnupg/private-keys-v1.d/, I confirm with:
gpg --list-secret-keys
Non-Interactive Generation
For CI pipelines or reproducible containers, I lean on batch parameters:
cat >gpg-batch <<'EOF'
Key-Type: RSA
Key-Length: 3072
Subkey-Type: RSA
Subkey-Length: 3072
Name-Real: Alice Example
Name-Email: alice@example.com
Expire-Date: 2y
Passphrase: correct horse battery staple
%commit
EOF
gpg --batch --generate-key gpg-batch
Batch mode keeps infrastructure bootstrap scripts deterministic and avoids interactive prompts.
Working with Subkeys
A primary key certifies your identity, while subkeys do the day-to-day work. I treat them like specialized tools that can be rotated independently.
Key Subtypes at a Glance
Signing (S)
expect <<'EOF'
spawn gpg --expert --edit-key your@email.com
expect "gpg>"
send "addkey\r"
expect "Your selection?"
send "4\r" # RSA (sign only)
expect "What keysize do you want?"
send "4096\r"
expect "Key is valid for?"
send "2y\r"
expect "Is this correct?"
send "y\r"
expect "Really create?"
send "y\r"
expect "gpg>"
send "save\r"
expect eof
EOF
- Purpose: signing code, emails, releases.
Encryption (E)
expect <<'EOF'
spawn gpg --expert --edit-key your@email.com
expect "gpg>"
send "addkey\r"
expect "Your selection?"
send "6\r" # RSA (encrypt only)
expect "What keysize do you want?"
send "4096\r"
expect "Key is valid for?"
send "2y\r"
expect "Is this correct?"
send "y\r"
expect "Really create?"
send "y\r"
expect "gpg>"
send "save\r"
expect eof
EOF
- Purpose: receiving confidential data.
Authentication
expect <<'EOF'
spawn gpg --expert --edit-key your@email.com
expect "gpg>"
send "addkey\r"
expect "Your selection?"
send "8\r" # set your own capabilities
expect "Your selection?"
send "S\r" # toggle sign off
expect "Your selection?"
send "E\r" # toggle encrypt off
expect "Your selection?"
send "A\r" # leave authenticate on
expect "Your selection?"
send "Q\r"
expect "What keysize do you want?"
send "4096\r"
expect "Key is valid for?"
send "2y\r"
expect "Is this correct?"
send "y\r"
expect "Really create?"
send "y\r"
expect "gpg>"
send "save\r"
expect eof
EOF
- Purpose: SSH access and system logins via
gpg-agent.
Inspecting and Managing Keys
Reading gpg --list-keys
pub ed25519 2025-11-05 [SC] [expires: 2028-11-04]
XXXXxXXXXXXXXXXXXXXXXXXXXXXXXXX
uid [ultimate] xxxxx <xxxxxx@gmail.com>
sub cv25519 2025-11-05 [E] [expires: 2028-11-04]
- pub line: algorithm, creation date, capability flags
[S](sign),[C](certify),[E](encrypt),[A](authenticate),[R](revocation). - Fingerprint: 40 hex characters that must match what the owner publishes elsewhere.
- uid entries: every declared identity plus trust level.
- sub blocks: encryption or authentication subkeys with their own expiration timers.
For Git signing I rely on secret key fingerprints:
gpg --list-secret-keys --keyid-format LONG
Need to tweak a key? gpg --edit-key KEYID exposes expiry changes, new user IDs, and cross-signing. To double-check every subkey, I run:
gpg --list-keys --with-subkey-fingerprints your@email.com
Encrypting and Decrypting Data
Encrypting to a Recipient
# Basic encryption
gpg --output message.asc --encrypt --recipient bob@example.com message.txt
# Specify your sender identity
gpg --output message.asc --encrypt \
--recipient bob@example.com \
--local-user your@email.com \
message.txt
--armoremits ASCII-armored output for chat, email, or Markdown:
-----BEGIN PGP MESSAGE-----
Version: GnuPG v2.0.22 (GNU/Linux) hQEMA12345678901234
...content...
-----END PGP MESSAGE-----
- GPG automatically selects the freshest valid encryption subkey for each recipient. If you only have their primary key, refresh from a key server before sending anything sensitive.
- Only the holder of the matching private encryption subkey can decrypt your message — the primary key simply vouches for the subkey’s legitimacy.
Signing and Encrypting Together
gpg --output message.txt.gpg --encrypt \
--sign --local-user a@example.com \
--recipient bob@example.com message.txt
When I decrypt that file, GPG verifies the embedded signature automatically. There’s no way to verify the signature separately because it sits inside the encrypted payload.
Detached Signatures for Separate Verification
gpg --output message.txt.sig --detach-sign message.txt
gpg --output message.txt.gpg --encrypt --recipient bob@example.com message.txt
Recipients need both files:
gpg --output message.txt --decrypt message.txt.gpg
gpg --verify message.txt.sig message.txt
For transparency I often share gpg --import sender-public-key.asc or even pipe a full -----BEGIN PGP PUBLIC KEY BLOCK----- directly into gpg --import.
Show Encryption Details and Signers
gpg --list-packets message.asc
This reveals the signing key ID, timestamps, and packet structure without needing a passphrase. It’s an easy way to audit who encrypted or signed a blob.
Decrypting
gpg --output message.txt --decrypt message.asc
GPG prompts for the appropriate private subkey passphrase, prints signature status if available, and writes the plaintext. Treat warnings like “untrusted signature” seriously — they signal you haven’t established a trust path to that key yet.
Stay Ready with Revocation Certificates
If I ever lose a private key or forget the passphrase, I want a revocation certificate ready to go:
gpg --output alice-revocation.asc --gen-revoke youremail@example.com
I store it offline (encrypted USB, paper, or a hardware token) so I can upload it to key servers or WKD if compromise strikes.
Exporting Your Public Key
Sharing my key is as simple as:
gpg --armor --export youremail@example.com > alice-public.asc
That ASCII block can live on a personal site, a README, or a CI repository to automate trust bootstrapping.
Integrating with Everyday Tools
- SSH: enable
enable-ssh-supportingpg-agent.confto let hardware-backed authentication subkeys act like SSH keys. - Git:
git config --global user.signingkey KEYIDplusgit config --global commit.gpgsign trueensures every commit carries a signature. - Secrets management: tools like
pass,gopass, andgit-cryptlean on GPG for encryption, so well-managed subkeys simplify app secrets.
Understanding how GPG plugs into these workflows keeps passphrase prompts manageable and makes automation-friendly PGP key management much smoother.
Wrapping Up
GPG remains one of my favorite ways to build trust across open systems. We covered interactive and batch key creation, smart use of subkeys, encryption workflows, packet inspection, revocation readiness, and integrations that power secure email and software releases.
Thanks for reading. If you liked the article, join my newsletter for hands-on cryptography and AI-engineering tactics . Have a question or a favorite GnuPG trick? Drop it in the comments so we can learn from each other.
메타데이터
- post_id
- 9ec27ab2c2eb
- slug
- introduction-to-gnupg-9ec27ab2c2eb
- url
- https://blog1.neuralengineer.org/introduction-to-gnupg-9ec27ab2c2eb
- canonical_url
- https://blog1.neuralengineer.org/introduction-to-gnupg-9ec27ab2c2eb
- author_url
- https://medium.com/@pi45757
- status
- ok
- fetched_at
- 2026-07-15 15:09:51