gpg.md (74078B)
1 --- 2 title: "GPG" 3 description: "GnuPG keys, encryption/decryption, signing/verification, keyservers, trust and revocation." 4 category: cryptography 5 tags: [cryptography, encryption, pgp] 6 tools: [GPG, GnuPG] 7 difficulty: intermediate 8 updated: "2026-08-09" 9 source: "vault:Cryptography/GPG - Cheatsheet markdown.md" 10 --- 11 12 # GPG 13 14 15 --- 16 17 > **Note —** 18 > Advanced, copy-ready [GnuPG](https://www.gnupg.org/) reference for local key management, signing, encryption, verification, and automation. Examples favour full fingerprints, explicit signing identities, and deliberate recipient lists. Commands were checked against the installed **GnuPG 2.5.21** client. 19 20 > **Note —** 21 > 1. A fingerprint identifies a key; it is safe to share after independent verification. A private key, passphrase, decrypted data, and private-key backup are not. 22 > 2. Never delete a secret key before an encrypted offline backup and revocation certificate exist. 23 > 3. Keyservers are effectively append-only. Revoking a compromised published key is possible; reliably removing it from all keyservers is not. 24 25 --- 26 27 ## // ADVANCED_OPERATOR_QUICKSTART `fas:ClipboardList` 28 29 ### 1. Use full fingerprints and explicit identities 30 31 ```bash 32 # Replace every placeholder with a full 40-hex-character OpenPGP fingerprint. 33 export YOUR_FPR='0123456789ABCDEF0123456789ABCDEF01234567' 34 export RECIPIENT_FPR='89ABCDEF0123456789ABCDEF0123456789ABCDEF' 35 36 # Show the secret keys that can sign and public keys that can encrypt. 37 gpg --list-secret-keys --keyid-format LONG --with-fingerprint 38 gpg --list-keys --keyid-format LONG --with-fingerprint 39 ``` 40 41 > **Note —** + Why fingerprints matter `fas:Lightbulb` 42 > A short key ID is not a unique trust anchor. Verify a full fingerprint through an independent channel, then use that fingerprint with `--local-user` (`-u`) and `--recipient` (`-r`). 43 44 ### 2. Sign with a non-default private key 45 46 ```bash 47 # Detached, ASCII-armored signature: creates file.pdf.asc 48 gpg --local-user "$YOUR_FPR" --detach-sign --armor file.pdf 49 50 # Detached binary signature: creates file.pdf.sig 51 gpg --local-user "$YOUR_FPR" --detach-sign file.pdf 52 53 # Embedded binary signature: creates file.pdf.gpg 54 gpg --local-user "$YOUR_FPR" --sign file.pdf 55 56 # Human-readable cleartext signature: creates message.txt.asc 57 gpg --local-user "$YOUR_FPR" --clearsign message.txt 58 ``` 59 60 > **Note —** + Signing selection 61 > 1. `--local-user` / `-u` chooses the signing identity and overrides `default-key`. 62 > 2. `--detach-sign` keeps the original file unchanged and is the normal choice for software artifacts. 63 > 3. `--armor` produces portable text output; omit it for compact binary output. 64 65 ### 3. Encrypt to explicit public keys 66 67 ```bash 68 # Binary encrypted output: creates file.pdf.gpg 69 gpg --recipient "$RECIPIENT_FPR" --encrypt file.pdf 70 71 # ASCII-armored encrypted output: creates file.pdf.asc 72 gpg --recipient "$RECIPIENT_FPR" --armor --encrypt file.pdf 73 74 # Encrypt to several people; each listed recipient can decrypt. 75 gpg --recipient "$RECIPIENT_FPR" \ 76 --recipient "$YOUR_FPR" \ 77 --armor --encrypt file.pdf 78 ``` 79 80 > **Note —** + Include yourself deliberately `fas:TriangleExclamation` 81 > Encryption only includes the recipients you specify, plus any separately configured `encrypt-to` recipient. If you encrypt only to someone else, you may be unable to decrypt your own output later. Add your verified encryption-capable key as another `--recipient` when you need future access. 82 83 ### 4. Encrypt and sign with different keys 84 85 ```bash 86 # Sign as YOUR_FPR; encrypt only for the recipient. 87 gpg --local-user "$YOUR_FPR" \ 88 --recipient "$RECIPIENT_FPR" \ 89 --sign --encrypt file.pdf 90 91 # Sign as YOUR_FPR; encrypt for the recipient and yourself. 92 gpg --local-user "$YOUR_FPR" \ 93 --recipient "$RECIPIENT_FPR" \ 94 --recipient "$YOUR_FPR" \ 95 --armor --sign --encrypt file.pdf 96 ``` 97 98 ### 5. Verify and decrypt safely 99 100 ```bash 101 # Verify a detached signature against its original file. 102 gpg --verify file.pdf.asc file.pdf 103 104 # Verify an embedded signature. 105 gpg --verify signed-file.gpg 106 107 # Decrypt to a deliberate output path. 108 gpg --output decrypted-file.pdf --decrypt file.pdf.gpg 109 ``` 110 111 > **Note —** + What a successful verification proves 112 > A good signature proves that a matching private key signed the bytes you verified. It does **not** establish a real-world identity until you have independently verified the signing key’s fingerprint and trust context. 113 114 --- 115 116 ## // DEFAULT_KEY_&_RECIPIENT_CONTROL 117 118 ### 1. Understand the four settings 119 120 | Setting | Effect | Prefer for intentional workflows | 121 |---|---|---| 122 | `default-key <FPR>` | Default signing identity when `--local-user` is omitted | Explicit `--local-user "$YOUR_FPR"` | 123 | `default-recipient <FPR>` | Encrypts to this key when `--recipient` is omitted | Explicit `--recipient "$RECIPIENT_FPR"` | 124 | `default-recipient-self` | Uses the default signing key as encryption recipient when recipients are omitted | Add your own `--recipient "$YOUR_FPR"` explicitly | 125 | `encrypt-to <FPR>` | Always adds this recipient to encryption, even when `--recipient` is supplied | Explicit recipient list when you need predictable output | 126 127 ### 2. Remove a configured default key without deleting the key 128 129 ```bash 130 # Locate the active GnuPG home and open the primary configuration file. 131 gpgconf --list-dirs homedir 132 "${EDITOR:-vi}" "$(gpgconf --list-dirs homedir)/gpg.conf" 133 ``` 134 135 Remove or comment out each directive you do not want, for example: 136 137 ```conf 138 # default-key 0123456789ABCDEF0123456789ABCDEF01234567 139 # default-recipient 0123456789ABCDEF0123456789ABCDEF01234567 140 # default-recipient-self 141 # encrypt-to 0123456789ABCDEF0123456789ABCDEF01234567 142 ``` 143 144 ```bash 145 # Inspect the defaults reported by the current configuration. 146 gpgconf --list-options gpg | grep -E '^(default-key|default-recipient|encrypt-to):' 147 148 # One-command override: disable recipient defaults for this invocation only. 149 gpg --no-default-recipient --recipient "$RECIPIENT_FPR" --encrypt file.pdf 150 ``` 151 152 > **Note —** + Removing a default is not deleting a key `fas:TriangleExclamation` 153 > 1. Removing `default-key` only clears the configured signing preference. If you omit `--local-user`, GnuPG can still fall back to the first usable secret key. 154 > 2. `--no-default-recipient` resets `default-recipient` and `default-recipient-self` for one command; do **not** put it in `gpg.conf`. 155 > 3. For repeatable work, always specify both the signer and every intended recipient on the command line. 156 157 ### 3. Delete a key from the local keyring — separate, destructive action 158 159 ```bash 160 # First: create an encrypted secret-key backup and an offline revocation certificate. 161 gpg --armor --output "${YOUR_FPR}.secret.asc" --export-secret-keys "$YOUR_FPR" 162 gpg --output "${YOUR_FPR}.revocation.asc" --generate-revocation "$YOUR_FPR" 163 164 # Review the exact fingerprint, then remove the local secret and public key. 165 gpg --fingerprint "$YOUR_FPR" 166 gpg --delete-secret-and-public-key "$YOUR_FPR" 167 ``` 168 169 > **Note —** + Deletion checklist `fas:Skull` 170 > 1. Store the exported private key and revocation certificate offline, encrypted, and separately from the passphrase. 171 > 2. Deletion removes the key from this local keyring; it does not retract a public key already uploaded to a keyserver. 172 > 3. If the key is compromised rather than simply unused, publish the revocation certificate after validating its contents. 173 174 --- 175 176 ## // SCRIPTING_&_ISOLATED_KEYRINGS `fas:Terminal` 177 178 ### 1. Machine-readable listings and status output 179 180 ```bash 181 # Stable machine-readable key listing; do not parse the human-facing --list-keys output. 182 gpg --batch --with-colons --with-fingerprint --list-keys "$RECIPIENT_FPR" 183 184 # Capture structured status lines while verifying a detached signature. 185 gpg --batch --status-fd 1 --verify file.pdf.asc file.pdf 2>/dev/null 186 ``` 187 188 ### 2. Test an import in a disposable GnuPG home 189 190 ```bash 191 export TEST_GNUPGHOME="$(mktemp -d)" 192 chmod 700 "$TEST_GNUPGHOME" 193 194 gpg --homedir "$TEST_GNUPGHOME" --import candidate-key.asc 195 gpg --homedir "$TEST_GNUPGHOME" --with-fingerprint --list-keys 196 197 # Remove this temporary directory only after reviewing the imported key. 198 if [ -n "$TEST_GNUPGHOME" ] && [ -d "$TEST_GNUPGHOME" ]; then 199 rm -rf -- "$TEST_GNUPGHOME" 200 fi 201 unset TEST_GNUPGHOME 202 ``` 203 204 > **Note —** + Automation rules 205 > Use `--batch`, `--status-fd`, and `--with-colons` for scripts. Do not feed passphrases on the command line; use a controlled pinentry, agent, or a carefully designed file descriptor workflow instead. 206 207 --- 208 209 ## Quick Reference Command Matrix 210 211 **This table summarizes ALL GPG operations covered in this cheatsheet.** 212 213 > **Note —** - 📋 Quick Reference Cheat Sheet 214 > | # | Category | Command | Purpose | Key Flags | 215 > |:--|:---|:---|:---|:---| 216 > | 1 | Key Generation | `gpg --gen-key` | Generate new key pair (simplified) | Interactive prompts | 217 > | 2 | Key Generation | `gpg --full-generate-key` | Generate key with full options | Choose algorithm, size, expiry | 218 > | 3 | Key Generation | `gpg --quick-generate-key "Name <email>" ed25519 sign 1y` | Generate Ed25519 key programmatically | Modern algorithm | 219 > | 4 | Key Listing | `gpg --list-keys` | List all public keys | Alias: `gpg -k` | 220 > | 5 | Key Listing | `gpg --list-secret-keys` | List all private keys | Alias: `gpg -K` | 221 > | 6 | Key Listing | `gpg --list-keys --keyid-format long` | List keys with long IDs | Shows full key IDs | 222 > | 7 | Key Export | `gpg --export -a <key-id>` | Export public key (ASCII) | `-a` = armor (text format) | 223 > | 8 | Key Export | `gpg --export-secret-keys -a <key-id>` | Export private key (ASCII) | **Keep secure!** | 224 > | 9 | Key Import | `gpg --import <file>` | Import key from file | Public or private | 225 > | 10 | Key Import | `gpg --recv-keys <key-id>` | Download key from keyserver | Requires keyserver config | 226 > | 11 | Key Upload | `gpg --send-keys <key-id>` | Upload key to keyserver | Makes key discoverable | 227 > | 12 | Key Search | `gpg --search-keys "email@example.com"` | Search keyserver for key | Requires keyserver | 228 > | 13 | Key Deletion | `gpg --delete-key <key-id>` | Delete public key | Cannot have secret key | 229 > | 14 | Key Deletion | `gpg --delete-secret-key <key-id>` | Delete private key | Must be done first | 230 > | 15 | Key Editing | `gpg --edit-key <key-id>` | Interactive key editor | Commands: trust, expire, passwd | 231 > | 16 | Key Info | `gpg --fingerprint <key-id>` | Show key fingerprint | For verification | 232 > | 17 | Encryption (Asymmetric) | `gpg -e -r <recipient> <file>` | Encrypt file for recipient | Creates `.gpg` file | 233 > | 18 | Encryption (Asymmetric) | `gpg -e -a -r <recipient> <file>` | Encrypt with ASCII armor | Creates `.asc` file | 234 > | 19 | Encryption (Symmetric) | `gpg -c <file>` | Encrypt with passphrase | No keys needed | 235 > | 20 | Encryption (Symmetric) | `gpg -c --armor <file>` | Symmetric encryption (ASCII) | Password-based | 236 > | 21 | Decryption | `gpg -d <file>` | Decrypt file to stdout | Displays decrypted content | 237 > | 22 | Decryption | `gpg -o <output> -d <file>` | Decrypt to specific file | `-o` = output path | 238 > | 23 | Signing (Binary) | `gpg -s <file>` | Sign file (binary format) | Creates `.gpg` | 239 > | 24 | Signing (Clear) | `gpg --clearsign <file>` | Sign with readable message | Creates `.asc` | 240 > | 25 | Signing (Detached) | `gpg -b <file>` | Create detached signature | Creates `.sig` | 241 > | 26 | Signing (Detached ASCII) | `gpg -b -a <file>` | Detached signature (ASCII) | Creates `.asc` | 242 > | 27 | Sign + Encrypt | `gpg -se -r <recipient> <file>` | Sign then encrypt | Combined operation | 243 > | 28 | Verification | `gpg --verify <file>` | Verify embedded signature | Checks authenticity | 244 > | 29 | Verification | `gpg --verify <sig> <file>` | Verify detached signature | Two separate files | 245 > | 30 | Revocation | `gpg --gen-revoke --output revoke.asc <key-id>` | Generate revocation certificate | Create immediately | 246 > | 31 | Trust Management | `gpg --update-trustdb` | Rebuild trust database | After key changes | 247 > | 32 | Agent Control | `gpgconf --kill gpg-agent` | Restart GPG agent | Fix cache issues | 248 > | 33 | Configuration | `gpg --list-config` | Show configured options | Debugging | 249 > | 34 | Diagnostics | `gpg --check-trustdb` | Check trust database integrity | Troubleshooting | 250 251 **Key Terminology:** 252 1. **ASCII Armor**: Text-based encoding for binary GPG data (flag: `-a` or `--armor`) 253 2. **Key ID**: Unique identifier for a GPG key (short: 8 hex chars, long: 16 hex chars, fingerprint: 40 hex chars) 254 3. **Keyring**: Database storing all your GPG keys (`~/.gnupg/`) 255 4. **Passphrase**: Password protecting your private key 256 5. **Recipient**: Person you're encrypting a message for (flag: `-r`) 257 6. **Web of Trust**: Decentralized trust model based on key signing 258 7. **Subkey**: Secondary key for specific operations (can be rotated without changing master key) 259 8. **Revocation Certificate**: Document that invalidates a key if compromised 260 261 --- 262 263 ## Understanding GnuPG and Public Key Cryptography 264 265 1. [**GnuPG (GNU Privacy Guard)**](https://gnupg.org/) is a complete and free implementation of the [**OpenPGP standard**](https://www.openpgp.org/) as defined by [**RFC 4880**](https://www.rfc-editor.org/rfc/rfc4880). 266 2. It provides **hybrid encryption** combining the convenience of public-key cryptography with the speed of symmetric encryption. 267 3. [**Public-key cryptography**](https://en.wikipedia.org/wiki/Public-key_cryptography) uses two mathematically related keys: 268 4. **Public key**: Shared openly, used by others to encrypt messages to you or verify your signatures 269 5. **Private key**: Kept secret, used to decrypt messages sent to you or create digital signatures 270 6. The [**Web of Trust**](https://en.wikipedia.org/wiki/Web_of_trust) model allows users to certify each other's keys through signatures, building a decentralized trust network without central authorities. 271 7. **Use cases** include: 272 8. Encrypting sensitive emails and documents 273 9. Digitally signing code releases and Git commits 274 10. Authenticating software downloads via detached signatures 275 11. Securing SSH authentication using GPG keys 276 12. Encrypting password manager databases 277 13. GPG operates on the principle of **confidentiality** (encryption prevents unauthorized reading), **authenticity** (signatures prove sender identity), and **integrity** (tampering detection). 278 279 --- 280 281 ## Security Model and Cryptographic Algorithms 282 283 1. GPG supports multiple **public-key algorithms**: 284 2. [**RSA**](https://en.wikipedia.org/wiki/RSA_(cryptosystem)): Traditional algorithm, minimum 2048-bit (4096-bit recommended) 285 3. [**Ed25519**](https://en.wikipedia.org/wiki/EdDSA): Modern elliptic curve algorithm, faster and more secure with smaller keys 286 4. **DSA/ElGamal**: Legacy algorithms, no longer recommended 287 5. **Symmetric encryption** algorithms (for actual data encryption): 288 6. [**AES256**](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard): Industry standard, recommended 289 7. **AES192/AES128**: Also secure but less common 290 8. **3DES**: Deprecated, should be disabled 291 9. **Hash algorithms** for integrity verification: 292 10. [**SHA512/SHA384/SHA256**](https://en.wikipedia.org/wiki/SHA-2): Modern, secure 293 11. **SHA1**: Deprecated due to collision vulnerabilities 294 12. **MD5**: Completely broken, never use 295 13. The **encryption process** works as follows: 296 14. GPG generates a random **session key** (symmetric) 297 15. The message is encrypted with the session key using symmetric encryption (fast) 298 16. The session key is encrypted with the recipient's **public key** (slow but small) 299 17. Both the encrypted message and encrypted session key are bundled together 300 18. The **decryption process** reverses this: 301 19. Your **private key** decrypts the session key 302 20. The session key decrypts the actual message 303 21. **Digital signatures** provide authenticity: 304 22. GPG creates a hash of the message 305 23. The hash is encrypted with your **private key** (this is the signature) 306 24. Recipients decrypt the signature with your **public key** and compare hashes 307 308 --- 309 310 ## Key Management Best Practices 311 312 **Key generation recommendations:** 313 1. Use **Ed25519** for new keys (modern, fast, secure) 314 2. If compatibility required, use **RSA 4096-bit** 315 3. Always set an **expiration date** (1-2 years), extend as needed 316 4. Use a **strong passphrase** (minimum 20 characters, store in password manager) 317 318 **Master key and subkey architecture:** 319 1. Keep your **master key offline** (air-gapped computer or hardware token) 320 2. Use **subkeys** for daily operations (signing, encryption, authentication) 321 3. If a subkey is compromised, revoke only the subkey, not the master key 322 4. Subkeys can be rotated without affecting your key identity 323 324 **Backup strategy:** 325 1. Export your **private key** to encrypted USB drive 326 2. Store revocation certificate in a separate secure location 327 3. Consider **paper backups** using [paperkey](https://www.jabberwocky.com/software/paperkey/) 328 4. Test restoration process regularly 329 330 **Trust and verification:** 331 1. **Always verify fingerprints** through a separate channel (phone call, in person, video chat) 332 2. Sign keys only after identity verification 333 3. Set appropriate **trust levels**: unknown, never, marginal, full, ultimate 334 4. Attend [**key signing parties**](https://en.wikipedia.org/wiki/Key_signing_party) to expand Web of Trust 335 336 **Key distribution:** 337 1. Upload public keys to **keyservers**: [keys.openpgp.org](https://keys.openpgp.org/), [keyserver.ubuntu.com](https://keyserver.ubuntu.com/) 338 2. Publish on personal website or GitHub 339 3. Include in email signatures or social media profiles 340 4. Use [**Keybase**](https://keybase.io/) for cryptographic identity verification 341 342 **Revocation planning:** 343 1. Generate revocation certificate **immediately** after key creation 344 2. Store offline in secure location with instructions 345 3. Distribute revocation certificate to keyservers if key compromised 346 4. Create reason-specific revocations (compromised vs. superseded) 347 348 --- 349 350 ## Key Generation and Initial Setup 351 352 **Simplified Key Generation (Recommended for Beginners):** 353 354 ```bash 355 gpg --gen-key 356 ``` 357 358 ```plaintext 359 gpg (GnuPG) 2.4.0; Copyright (C) 2021 Free Software Foundation, Inc. 360 361 Please select what kind of key you want: 362 (1) RSA and RSA (default) 363 (2) DSA and Elgamal 364 (3) DSA (sign only) 365 (4) RSA (sign only) 366 Your selection? 1 367 368 RSA keys may be between 1024 and 4096 bits long. 369 What keysize do you want? (3072) 4096 370 371 Please specify how long the key should be valid. 372 0 = key does not expire 373 <n> = key expires in n days 374 <n>w = key expires in n weeks 375 <n>m = key expires in n months 376 <n>y = key expires in n years 377 Key is valid for? (0) 2y 378 379 Real name: John Doe 380 Email address: john.doe@example.com 381 Comment: Work key 382 383 You selected this USER-ID: 384 "John Doe (Work key) <john.doe@example.com>" 385 386 Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O 387 388 [Enter passphrase when prompted] 389 390 gpg: key 0x1234567890ABCDEF marked as ultimately trusted 391 public and secret key created and signed. 392 ``` 393 394 **Process Overview:** 395 1. **Algorithm selection**: Default RSA and RSA creates both signing and encryption subkeys 396 2. **Key size**: 4096 bits provides strong security (2048 minimum, 3072 default) 397 3. **Expiration**: Setting expiry forces periodic review and prevents orphaned keys 398 4. **User ID**: Combines name, email, and optional comment (email most important for searches) 399 5. **Passphrase**: Encrypts your private key on disk using symmetric encryption 400 401 **What happens during generation:** 402 1. GPG collects entropy from system randomness (`/dev/random`) 403 2. Generates prime numbers for RSA keys 404 3. Creates master key and subkeys 405 4. Generates revocation certificate automatically (stored in `~/.gnupg/openpgp-revocs.d/`) 406 5. Updates local trustdb 407 408 **Alternative approaches:** 409 1. `gpg --full-generate-key` — Provides more algorithm options 410 2. `gpg --quick-generate-key` — Non-interactive, scriptable 411 3. `gpg --expert --full-generate-key` — Advanced options including curve selection 412 413 --- 414 415 ## Advanced Key Generation with Modern Algorithms 416 417 **Generate Ed25519 Key (Recommended for 2024+):** 418 419 ```bash 420 gpg --quick-generate-key "John Doe <john.doe@example.com>" ed25519 sign 1y 421 ``` 422 423 ```plaintext 424 gpg: key 0xABCDEF1234567890 marked as ultimately trusted 425 gpg: revocation certificate stored as '/home/user/.gnupg/openpgp-revocs.d/ABCDEF1234567890.rev' 426 public and secret key created and signed. 427 428 pub ed25519 2025-12-30 [SC] [expires: 2026-12-30] 429 ABCDEF1234567890ABCDEF1234567890ABCDEF12 430 uid John Doe <john.doe@example.com> 431 ``` 432 433 **Add Encryption Subkey:** 434 435 ```bash 436 gpg --quick-add-key ABCDEF1234567890 cv25519 encr 1y 437 ``` 438 439 ```plaintext 440 pub ed25519 2025-12-30 [SC] [expires: 2026-12-30] 441 ABCDEF1234567890ABCDEF1234567890ABCDEF12 442 uid [ultimate] John Doe <john.doe@example.com> 443 sub cv25519 2025-12-30 [E] [expires: 2026-12-30] 444 ``` 445 446 **Syntax:** `gpg --quick-generate-key "<name> <email>" <algorithm> <usage> <expiry>` 447 448 | Parameter | Purpose | 449 |:--|:--| 450 | `--quick-generate-key` | Non-interactive key generation | 451 | `"Name <email>"` | User ID string (quoted if contains spaces) | 452 | `ed25519` | Modern elliptic curve signing algorithm | 453 | `sign` | Key usage (sign, cert, auth, encr) | 454 | `1y` | Expires in 1 year (also: 2m=2 months, 3w=3 weeks, 0=never) | 455 456 **Why Ed25519 is superior:** 457 1. **Smaller keys**: 256-bit Ed25519 ≈ 3072-bit RSA security 458 2. **Faster operations**: 10-100x faster than RSA 459 3. **Modern cryptography**: Based on Curve25519, designed by Daniel J. Bernstein 460 4. **Resistance to side-channel attacks**: Constant-time implementations 461 462 **Key usage flags explained:** 463 1. **[C]**: Certify (sign other keys, master key capability) 464 2. **[S]**: Sign (create digital signatures on data) 465 3. **[E]**: Encrypt (receive encrypted messages) 466 4. **[A]**: Authenticate (use for SSH authentication) 467 468 **Adding subkeys:** 469 1. Use `--quick-add-key` with master key ID 470 2. Specify algorithm (cv25519 for encryption, ed25519 for signing) 471 3. Different expiry dates for different subkeys is common practice 472 4. Authentication subkey: `gpg --quick-add-key <keyid> ed25519 auth 1y` 473 474 --- 475 476 ## Listing and Inspecting Keys 477 478 **List all public keys:** 479 480 ```bash 481 gpg --list-keys --keyid-format long 482 ``` 483 484 ```plaintext 485 /home/user/.gnupg/pubring.kbx 486 -------------------------------- 487 pub rsa4096/0x1234567890ABCDEF 2025-12-30 [SC] [expires: 2027-12-30] 488 ABCDEF1234567890ABCDEF1234567890ABCDEF12 489 uid [ultimate] John Doe (Work key) <john.doe@example.com> 490 sub rsa4096/0x9876543210FEDCBA 2025-12-30 [E] [expires: 2027-12-30] 491 492 pub ed25519/0xDEADBEEFCAFEBABE 2025-12-28 [SC] [expires: 2026-12-28] 493 DEADBEEFCAFEBABEDEADBEEFCAFEBABEDEADBEEF 494 uid [ unknown] Alice Smith <alice@example.com> 495 sub cv25519/0xBABECAFEDEADBEEF 2025-12-28 [E] [expires: 2026-12-28] 496 ``` 497 498 **List private (secret) keys:** 499 500 ```bash 501 gpg --list-secret-keys --keyid-format long 502 ``` 503 504 ```plaintext 505 /home/user/.gnupg/pubring.kbx 506 -------------------------------- 507 sec rsa4096/0x1234567890ABCDEF 2025-12-30 [SC] [expires: 2027-12-30] 508 ABCDEF1234567890ABCDEF1234567890ABCDEF12 509 uid [ultimate] John Doe (Work key) <john.doe@example.com> 510 ssb rsa4096/0x9876543210FEDCBA 2025-12-30 [E] [expires: 2027-12-30] 511 ``` 512 513 **Show key fingerprint:** 514 515 ```bash 516 gpg --fingerprint john.doe@example.com 517 ``` 518 519 ```plaintext 520 pub rsa4096 2025-12-30 [SC] [expires: 2027-12-30] 521 ABCD EF12 3456 7890 ABCD EF12 3456 7890 ABCD EF12 522 uid [ultimate] John Doe (Work key) <john.doe@example.com> 523 sub rsa4096 2025-12-30 [E] [expires: 2027-12-30] 524 ``` 525 526 **Understanding the output:** 527 528 | Field | Meaning | 529 |:--|:--| 530 | `pub` | Public key | 531 | `sec` | Secret (private) key | 532 | `sub` | Public subkey | 533 | `ssb` | Secret subkey | 534 | `rsa4096` | Algorithm and key size | 535 | `0x1234...CDEF` | Long key ID (16 hex characters) | 536 | `2025-12-30` | Creation date | 537 | `[SC]` | Key capabilities: Sign, Certify | 538 | `[E]` | Key capability: Encrypt | 539 | `[expires: 2027-12-30]` | Expiration date | 540 | `[ultimate]` | Trust level (your own keys) | 541 | `[unknown]` | Trust level (unverified keys) | 542 543 **Trust levels explained:** 544 1. **unknown**: No trust decision made 545 2. **never**: Explicitly distrusted 546 3. **marginal**: Some confidence in key ownership 547 4. **full**: High confidence in key ownership 548 5. **ultimate**: Your own keys (absolute trust) 549 550 **Key ID formats:** 551 1. **Short (8 hex chars)**: `0xABCDEF12` — Vulnerable to collisions, deprecated 552 2. **Long (16 hex chars)**: `0x1234567890ABCDEF` — Recommended minimum 553 3. **Fingerprint (40 hex chars)**: Full SHA-1 hash of public key — Most secure, use for verification 554 555 **Useful listing variations:** 556 1. `gpg -k` — Shorthand for `--list-keys` 557 2. `gpg -K` — Shorthand for `--list-secret-keys` 558 3. `gpg --list-keys --with-fingerprint` — Always show fingerprints 559 4. `gpg --list-keys --with-keygrip` — Show internal key identifiers 560 561 --- 562 563 ## Exporting Keys for Backup and Sharing 564 565 **Export public key (ASCII armor for sharing):** 566 567 ```bash 568 gpg --armor --export john.doe@example.com > john-doe-public.asc 569 ``` 570 571 ```plaintext 572 -----BEGIN PGP PUBLIC KEY BLOCK----- 573 574 mQINBGV2+8kBEADMq7YzL3p8vKYj9xJHR8nzJ+W3qTd5gFHJ2kL9xYp3qRV8sW7M 575 [... key material ...] 576 -----END PGP PUBLIC KEY BLOCK----- 577 ``` 578 579 **Export private key (keep secure!):** 580 581 ```bash 582 gpg --armor --export-secret-keys john.doe@example.com > john-doe-private.asc 583 ``` 584 585 ```plaintext 586 -----BEGIN PGP PRIVATE KEY BLOCK----- 587 588 lQdGBGV2+8kBEADMq7YzL3p8vKYj9xJHR8nzJ+W3qTd5gFHJ2kL9xYp3qRV8sW7M 589 [... encrypted private key material ...] 590 -----END PGP PRIVATE KEY BLOCK----- 591 ``` 592 593 **Export all keys (backup entire keyring):** 594 595 ```bash 596 gpg --armor --export > all-public-keys.asc 597 gpg --armor --export-secret-keys > all-private-keys.asc 598 ``` 599 600 **Export to clipboard (macOS):** 601 602 ```bash 603 gpg --armor --export john.doe@example.com | pbcopy 604 ``` 605 606 **Export binary format (smaller file size):** 607 608 ```bash 609 gpg --export john.doe@example.com > john-doe-public.gpg 610 ``` 611 612 **Syntax:** `gpg [--armor] --export [--output file] <key-id>` 613 614 | Flag | Purpose | 615 |:--|:--| 616 | `--armor` / `-a` | ASCII-armored output (text instead of binary) | 617 | `--export` | Export public keys | 618 | `--export-secret-keys` | Export private keys | 619 | `--export-secret-subkeys` | Export only subkeys (keep master offline) | 620 | `--output` / `-o` | Specify output file | 621 | `<key-id>` | Email, key ID, or fingerprint (omit for all keys) | 622 623 **ASCII armor vs. binary:** 624 1. **ASCII armor** (`.asc`): Text format, email-safe, larger size (~33% overhead) 625 2. **Binary** (`.gpg`): Smaller, more efficient, not text-safe 626 627 **Security considerations:** 628 1. **Private key exports** are encrypted with your passphrase 629 2. Store private key exports on **encrypted USB drives** or **offline media** 630 3. Never email or upload private keys to cloud services 631 4. Use `shred` or secure deletion when removing private key backups 632 633 **Advanced export scenarios:** 634 1. **Export master key only**: `gpg --export-secret-keys --armor <keyid>!` 635 2. **Export specific subkey**: `gpg --export-secret-subkeys --armor <subkeyid>!` 636 3. **Export with trust database**: Also backup `~/.gnupg/trustdb.gpg` 637 4. **Paper backup**: Use `paperkey` tool to create printable backup 638 639 --- 640 641 ## Importing Keys from Others 642 643 **Import from file:** 644 645 ```bash 646 gpg --import alice-public.asc 647 ``` 648 649 ```plaintext 650 gpg: key 0xDEADBEEFCAFEBABE: public key "Alice Smith <alice@example.com>" imported 651 gpg: Total number processed: 1 652 gpg: imported: 1 653 ``` 654 655 **Import from keyserver:** 656 657 ```bash 658 gpg --keyserver hkps://keys.openpgp.org --recv-keys 0xDEADBEEFCAFEBABE 659 ``` 660 661 ```plaintext 662 gpg: key 0xDEADBEEFCAFEBABE: public key "Alice Smith <alice@example.com>" imported 663 gpg: Total number processed: 1 664 gpg: imported: 1 665 gpg: marginal needed: 3 complete needed: 1 trust model: pgp 666 ``` 667 668 **Search keyserver for a key:** 669 670 ```bash 671 gpg --keyserver hkps://keys.openpgp.org --search-keys alice@example.com 672 ``` 673 674 ```plaintext 675 (1) Alice Smith <alice@example.com> 676 4096 bit RSA key 0xDEADBEEFCAFEBABE, created: 2025-12-28 677 Keys 1-1 of 1 for "alice@example.com". Enter number(s), N)ext, or Q)uit > 1 678 ``` 679 680 **Import from URL:** 681 682 ```bash 683 curl https://example.com/alice-key.asc | gpg --import 684 ``` 685 686 **Import and verify fingerprint:** 687 688 ```bash 689 gpg --import alice-public.asc 690 gpg --fingerprint alice@example.com 691 ``` 692 693 ```plaintext 694 pub rsa4096 2025-12-28 [SC] [expires: 2026-12-28] 695 DEAD BEEF CAFE BABE DEAD BEEF CAFE BABE DEAD BEEF 696 uid [ unknown] Alice Smith <alice@example.com> 697 ``` 698 699 **Syntax:** `gpg --import <file>` or `gpg --recv-keys <key-id>` 700 701 | Flag | Purpose | 702 |:--|:--| 703 | `--import` | Import keys from file or stdin | 704 | `--recv-keys` | Download and import from keyserver | 705 | `--search-keys` | Search keyserver interactively | 706 | `--keyserver <url>` | Specify keyserver to use | 707 | `--fingerprint` | Display key fingerprint after import | 708 709 **Post-import verification workflow:** 710 1. Import the key 711 2. Check fingerprint: `gpg --fingerprint <key-id>` 712 3. **Verify fingerprint out-of-band** (phone call, in person, verified website) 713 4. Sign the key if verified: `gpg --sign-key <key-id>` 714 5. Set trust level: `gpg --edit-key <key-id>` → `trust` command 715 716 **Popular keyservers:** 717 1. [**keys.openpgp.org**](https://keys.openpgp.org/): Modern, privacy-focused, verifies email 718 2. [**keyserver.ubuntu.com**](https://keyserver.ubuntu.com/): Pool of synchronized servers 719 3. **keys.gnupg.net**: Legacy, often used for software verification 720 721 **Keyserver operations:** 722 1. **Upload**: `gpg --send-keys <key-id>` 723 2. **Refresh all keys**: `gpg --refresh-keys` (updates signatures and expiry) 724 3. **Auto-retrieve**: Set `auto-key-retrieve` in `gpg.conf` 725 726 --- 727 728 ## Deleting Keys (Use with Caution) 729 730 **Delete public key:** 731 732 ```bash 733 gpg --delete-key alice@example.com 734 ``` 735 736 ```plaintext 737 gpg (GnuPG) 2.4.0; Copyright (C) 2021 Free Software Foundation, Inc. 738 739 pub rsa4096/0xDEADBEEFCAFEBABE 2025-12-28 Alice Smith <alice@example.com> 740 741 Delete this key from the keyring? (y/N) y 742 ``` 743 744 **Delete private key (must be done before deleting public key):** 745 746 ```bash 747 gpg --delete-secret-key john.doe@example.com 748 ``` 749 750 ```plaintext 751 sec rsa4096/0x1234567890ABCDEF 2025-12-30 John Doe (Work key) <john.doe@example.com> 752 753 Delete this key from the keyring? (y/N) y 754 This is a secret key! - really delete? (y/N) y 755 ``` 756 757 **Delete both secret and public key (shortcut):** 758 759 ```bash 760 gpg --delete-secret-and-public-key john.doe@example.com 761 ``` 762 763 **Important Notes on Key Deletion:** 764 765 1. **Deleting a private key is permanent** — cannot decrypt past messages without backup 766 2. **Deleting public key doesn't remove it from keyservers** — must publish revocation certificate 767 3. **Order matters**: Must delete private key before public key 768 4. **Subkeys are deleted with master key** — cannot selectively delete subkeys via command line 769 5. **Before deletion**: 770 6. Ensure you have backed up the private key 771 7. Generate and publish revocation certificate if key is public 772 8. Consider just revoking instead of deleting 773 9. **Use key editing for selective removal**: `gpg --edit-key <keyid>` → `key N` → `delkey` 774 775 --- 776 777 ## Interactive Key Editor 778 779 **Enter key editing mode:** 780 781 ```bash 782 gpg --edit-key john.doe@example.com 783 ``` 784 785 ```plaintext 786 gpg (GnuPG) 2.4.0; Copyright (C) 2021 Free Software Foundation, Inc. 787 788 Secret key is available. 789 790 sec rsa4096/0x1234567890ABCDEF 791 created: 2025-12-30 expires: 2027-12-30 usage: SC 792 trust: ultimate validity: ultimate 793 ssb rsa4096/0x9876543210FEDCBA 794 created: 2025-12-30 expires: 2027-12-30 usage: E 795 [ultimate] (1). John Doe (Work key) <john.doe@example.com> 796 797 gpg> help 798 quit quit this menu 799 save save and quit 800 help show this help 801 fpr show key fingerprint 802 grip show the keygrip 803 list list key and user IDs 804 uid select user ID N 805 key select subkey N 806 check check signatures 807 sign sign selected user IDs 808 adduid add a user ID 809 deluid delete selected user IDs 810 addkey add a subkey 811 delkey delete selected subkeys 812 expire change the expiration date for the key or selected subkeys 813 passwd change the passphrase 814 trust change the ownertrust 815 revkey revoke key or selected subkeys 816 817 gpg> 818 ``` 819 820 **Common Key Editing Tasks:** 821 822 **Change expiration date:** 823 1. Enter edit mode: `gpg --edit-key <key-id>` 824 2. Command: `expire` 825 3. Follow prompts to set new expiration 826 4. For subkeys: `key 1` to select, then `expire` 827 5. Save: `save` 828 829 **Change passphrase:** 830 1. Enter edit mode: `gpg --edit-key <key-id>` 831 2. Command: `passwd` 832 3. Enter old passphrase, then new passphrase twice 833 4. Save: `save` 834 835 **Set trust level:** 836 1. Enter edit mode: `gpg --edit-key <key-id>` 837 2. Command: `trust` 838 3. Select trust level (1-5): 839 4. 1 = I don't know or won't say 840 5. 2 = I do NOT trust 841 6. 3 = I trust marginally 842 7. 4 = I trust fully 843 8. 5 = I trust ultimately (own keys only) 844 9. Confirm and save 845 846 **Add new user ID (email):** 847 1. Enter edit mode: `gpg --edit-key <key-id>` 848 2. Command: `adduid` 849 3. Enter new name, email, comment 850 4. Command: `uid 1` to select new UID 851 5. Command: `primary` to make it primary 852 6. Save: `save` 853 854 **Revoke a key:** 855 1. Enter edit mode: `gpg --edit-key <key-id>` 856 2. Command: `revkey` 857 3. Select reason: 0=No reason, 1=Key compromised, 2=Key superseded, 3=Key no longer used 858 4. Confirm revocation 859 5. Save: `save` 860 6. Upload to keyserver: `gpg --send-keys <key-id>` 861 862 --- 863 864 ## Asymmetric Encryption (Public Key) 865 866 **Encrypt file for single recipient:** 867 868 ```bash 869 gpg --encrypt --recipient alice@example.com secret-document.txt 870 ``` 871 872 ```plaintext 873 [No output - creates secret-document.txt.gpg] 874 ``` 875 876 **Encrypt with ASCII armor (text-safe):** 877 878 ```bash 879 gpg --encrypt --armor --recipient alice@example.com secret-document.txt 880 ``` 881 882 ```plaintext 883 [Creates secret-document.txt.asc] 884 ``` 885 886 **Encrypt for multiple recipients:** 887 888 ```bash 889 gpg -e -a -r alice@example.com -r bob@example.com -r john.doe@example.com confidential.txt 890 ``` 891 892 ```plaintext 893 [Creates confidential.txt.asc - all three recipients can decrypt] 894 ``` 895 896 **Encrypt and specify output filename:** 897 898 ```bash 899 gpg --output encrypted-report.gpg --encrypt --recipient alice@example.com quarterly-report.pdf 900 ``` 901 902 **Encrypt stdin (terminal input):** 903 904 ```bash 905 echo "Meeting at 3pm tomorrow" | gpg -e -a -r alice@example.com > message.asc 906 ``` 907 908 **Encrypt multiline message:** 909 910 ```bash 911 cat <<EOF | gpg -e -a -r alice@example.com > secret-message.asc 912 Project Nightfall is a go. 913 Launch coordinates: 51.5074° N, 0.1278° W 914 Extraction team on standby. 915 EOF 916 ``` 917 918 **Syntax:** `gpg --encrypt --recipient <email> [--armor] [--output <file>] <input-file>` 919 920 | Flag | Purpose | 921 |:--|:--| 922 | `--encrypt` / `-e` | Encrypt the file | 923 | `--recipient` / `-r` | Specify recipient by email or key ID (repeatable) | 924 | `--armor` / `-a` | Output ASCII-armored text instead of binary | 925 | `--output` / `-o` | Specify output filename | 926 | `--hidden-recipient` / `-R` | Hide recipient identity in encrypted file | 927 928 **How it works:** 929 1. GPG looks up recipient's public key in your keyring 930 2. Generates random session key (symmetric) 931 3. Encrypts file with session key using AES-256 932 4. Encrypts session key with recipient's public key 933 5. Bundles both in output file 934 935 **Multiple recipients:** 936 1. Each `-r` flag adds another recipient 937 2. Session key is encrypted separately for each recipient's public key 938 3. Any recipient can decrypt using their private key 939 4. File size increases slightly with each recipient 940 941 **Pro tips:** 942 1. **Always encrypt to yourself too**: Add `-r your@email.com` so you can decrypt later 943 2. **Use `--encrypt-to` in config**: Automatically includes your key 944 3. **Hidden recipients**: Use `-R` instead of `-r` to prevent key ID leakage 945 4. **Trust warnings**: GPG warns if recipient key isn't trusted (use `--trust-model always` to bypass) 946 947 --- 948 949 ## Symmetric Encryption (Password-Based) 950 951 **Encrypt with passphrase (no keys needed):** 952 953 ```bash 954 gpg --symmetric confidential-notes.txt 955 ``` 956 957 ```plaintext 958 [Prompts for passphrase twice] 959 [Creates confidential-notes.txt.gpg] 960 ``` 961 962 **Symmetric encryption with ASCII armor:** 963 964 ```bash 965 gpg --symmetric --armor backup-codes.txt 966 ``` 967 968 ```plaintext 969 [Creates backup-codes.txt.asc] 970 ``` 971 972 **Specify cipher algorithm:** 973 974 ```bash 975 gpg --symmetric --cipher-algo AES256 --armor passwords.txt 976 ``` 977 978 **Encrypt from stdin:** 979 980 ```bash 981 echo "Quick secret note" | gpg -c --armor > note.asc 982 ``` 983 984 **Encrypt multiline content:** 985 986 ```bash 987 cat <<EOF | gpg -c --armor > database-credentials.asc 988 Database: production-db-01 989 Username: admin 990 Password: Tr0ub4dor&3 991 Host: db.internal.company.com:5432 992 EOF 993 ``` 994 995 **Syntax:** `gpg --symmetric [--cipher-algo <algorithm>] [--armor] <file>` 996 997 | Flag | Purpose | 998 |:--|:--| 999 | `--symmetric` / `-c` | Symmetric encryption (password-based) | 1000 | `--cipher-algo` | Specify encryption algorithm (default: AES-128) | 1001 | `--armor` / `-a` | ASCII-armored output | 1002 | `--output` / `-o` | Specify output file | 1003 1004 **Supported cipher algorithms:** 1005 1. **AES256** — Recommended (strongest) 1006 2. **AES192** — Strong 1007 3. **AES128** — Default (still secure) 1008 4. **CAMELLIA256** — Alternative to AES 1009 5. **TWOFISH** — Legacy 1010 1011 **When to use symmetric encryption:** 1012 1. **Personal backups**: No need for key exchange 1013 2. **Quick encryption**: Faster than asymmetric 1014 3. **File archives**: Password-protect sensitive files 1015 4. **Pre-shared secrets**: When secure channel for passphrase exists 1016 1017 **Security considerations:** 1018 1. Passphrase strength is critical (minimum 20 characters recommended) 1019 2. Use password manager to generate and store passphrases 1020 3. No forward secrecy (compromised passphrase exposes all files encrypted with it) 1021 4. Consider [**diceware**](https://www.eff.org/dice) for memorable but strong passphrases 1022 1023 **Decryption is identical to asymmetric**: `gpg -d file.gpg` (prompts for passphrase instead of using private key) 1024 1025 --- 1026 1027 ## Decrypting Files 1028 1029 **Decrypt to stdout (display):** 1030 1031 ```bash 1032 gpg --decrypt secret-document.txt.gpg 1033 ``` 1034 1035 ```plaintext 1036 gpg: encrypted with rsa4096 key, ID 0x9876543210FEDCBA, created 2025-12-30 1037 "John Doe (Work key) <john.doe@example.com>" 1038 This is the secret document content. 1039 Multiple lines preserved. 1040 ``` 1041 1042 **Decrypt to specific file:** 1043 1044 ```bash 1045 gpg --output decrypted.txt --decrypt secret-document.txt.gpg 1046 ``` 1047 1048 ```plaintext 1049 gpg: encrypted with rsa4096 key, ID 0x9876543210FEDCBA, created 2025-12-30 1050 "John Doe (Work key) <john.doe@example.com>" 1051 ``` 1052 1053 **Decrypt ASCII armored file:** 1054 1055 ```bash 1056 gpg --decrypt message.asc 1057 ``` 1058 1059 **Decrypt and pipe to another command:** 1060 1061 ```bash 1062 gpg -d encrypted-logs.txt.gpg | grep "ERROR" | less 1063 ``` 1064 1065 **Decrypt from stdin (paste encrypted content):** 1066 1067 ```bash 1068 gpg --decrypt <<EOF 1069 -----BEGIN PGP MESSAGE----- 1070 1071 hQIMA5h2VDIgzey6AQ/+K8Z3Jx4vN2M1pR7qL9... 1072 -----END PGP MESSAGE----- 1073 EOF 1074 ``` 1075 1076 **Decrypt clipboard content (macOS):** 1077 1078 ```bash 1079 pbpaste | gpg -d 1080 ``` 1081 1082 **Decrypt and copy result to clipboard (macOS):** 1083 1084 ```bash 1085 gpg -d secret.asc | pbcopy 1086 ``` 1087 1088 **Syntax:** `gpg --decrypt [--output <file>] <encrypted-file>` 1089 1090 | Flag | Purpose | 1091 |:--|:--| 1092 | `--decrypt` / `-d` | Decrypt the file | 1093 | `--output` / `-o` | Write decrypted content to file instead of stdout | 1094 | `--batch` | Non-interactive mode (no prompts) | 1095 | `--passphrase <pass>` | Supply passphrase via command line (insecure) | 1096 | `--passphrase-file <file>` | Read passphrase from file | 1097 1098 **What happens during decryption:** 1099 1. GPG reads the encrypted file header 1100 2. Identifies which key(s) can decrypt it 1101 3. Prompts for passphrase to unlock your private key 1102 4. Decrypts the session key using your private key 1103 5. Decrypts the actual content using the session key 1104 6. Outputs plaintext to stdout or file 1105 1106 **Output interpretation:** 1107 1. `encrypted with rsa4096 key` — Shows encryption algorithm and key type 1108 2. `ID 0x...` — Key ID that encrypted the file 1109 3. Name and email — Key owner (the recipient) 1110 1111 **Troubleshooting:** 1112 1. **"decryption failed: No secret key"** — You don't have the private key 1113 2. **"decryption failed: Bad passphrase"** — Wrong passphrase for private key 1114 3. **"WARNING: encrypted message has been manipulated"** — File integrity compromised (possible attack) 1115 4. **"gpg: public key decryption failed: Canceled"** — User cancelled passphrase entry 1116 1117 --- 1118 1119 ## Digital Signatures (Binary Format) 1120 1121 **Sign a file (creates compressed binary signature):** 1122 1123 ```bash 1124 gpg --sign important-document.txt 1125 ``` 1126 1127 ```plaintext 1128 [Creates important-document.txt.gpg] 1129 ``` 1130 1131 **Sign with ASCII armor:** 1132 1133 ```bash 1134 gpg --sign --armor report.pdf 1135 ``` 1136 1137 ```plaintext 1138 [Creates report.pdf.asc] 1139 ``` 1140 1141 **Sign with specific key:** 1142 1143 ```bash 1144 gpg --sign --local-user john.doe@example.com contract.txt 1145 ``` 1146 1147 **Extract content from signed file:** 1148 1149 ```bash 1150 gpg --decrypt signed-document.gpg 1151 ``` 1152 1153 ```plaintext 1154 gpg: Signature made Mon 30 Dec 2025 14:32:15 GMT 1155 gpg: using RSA key 0x1234567890ABCDEF 1156 gpg: Good signature from "John Doe (Work key) <john.doe@example.com>" [ultimate] 1157 [Original file content displayed] 1158 ``` 1159 1160 **Syntax:** `gpg --sign [--local-user <key-id>] [--armor] <file>` 1161 1162 | Flag | Purpose | 1163 |:--|:--| 1164 | `--sign` / `-s` | Create binary signature | 1165 | `--local-user` / `-u` | Specify which key to sign with | 1166 | `--armor` / `-a` | ASCII-armored output | 1167 | `--output` / `-o` | Specify output filename | 1168 1169 **What binary signing does:** 1170 1. Compresses the original file 1171 2. Creates hash of the compressed data 1172 3. Encrypts hash with your private key (this is the signature) 1173 4. Bundles original + signature in `.gpg` file 1174 1175 **Characteristics:** 1176 1. Original file is embedded in the signature file 1177 2. Smaller than clear-signing (compression applied) 1178 3. Not human-readable (binary format) 1179 4. To view content, must decrypt: `gpg -d file.gpg` 1180 1181 **Use cases:** 1182 1. Software releases (Linux packages) 1183 2. Binary files (executables, archives) 1184 3. When file content doesn't need to be readable without verification 1185 1186 --- 1187 1188 ## Clear-Text Signatures (Human-Readable) 1189 1190 **Sign with readable message:** 1191 1192 ```bash 1193 gpg --clearsign announcement.txt 1194 ``` 1195 1196 ```plaintext 1197 [Creates announcement.txt.asc] 1198 ``` 1199 1200 **Content of clear-signed file:** 1201 1202 ```plaintext 1203 -----BEGIN PGP SIGNED MESSAGE----- 1204 Hash: SHA512 1205 1206 This is the original message content. 1207 It remains completely readable. 1208 Anyone can see this text without GPG. 1209 -----BEGIN PGP SIGNATURE----- 1210 1211 iQIzBAEBCgAdFiEErN3xKzP4yKWaLZvzEjRWeJCrze8FAmV3FNMACgkQEjRWeJCr 1212 ze/xKRAAiJ4K3mN9pQZ7vR2XjL... 1213 -----END PGP SIGNATURE----- 1214 ``` 1215 1216 **Sign from terminal input:** 1217 1218 ```bash 1219 cat <<EOF | gpg --clearsign 1220 Official company announcement: 1221 Our Q4 earnings exceeded expectations. 1222 Revenue: £12.5M (up 23% YoY) 1223 Signed by CEO 1224 EOF 1225 ``` 1226 1227 **Sign and save to file:** 1228 1229 ```bash 1230 cat <<EOF | gpg --clearsign > announcement.asc 1231 Security Advisory: Patch immediately 1232 CVE-2025-12345 affects versions 1.0-2.3 1233 Update to version 2.4 or later 1234 EOF 1235 ``` 1236 1237 **Sign with specific key:** 1238 1239 ```bash 1240 gpg --clearsign --local-user john.doe@example.com statement.txt 1241 ``` 1242 1243 **Syntax:** `gpg --clearsign [--local-user <key-id>] <file>` 1244 1245 | Flag | Purpose | 1246 |:--|:--| 1247 | `--clearsign` | Create clear-text signature | 1248 | `--local-user` / `-u` | Specify signing key | 1249 | `--output` / `-o` | Specify output file | 1250 | `--digest-algo` | Choose hash algorithm (default: SHA256) | 1251 1252 **Structure of clear-signed message:** 1253 1. **Header**: `-----BEGIN PGP SIGNED MESSAGE-----` and hash algorithm 1254 2. **Blank line** 1255 3. **Original message**: Unmodified, human-readable 1256 4. **Signature block**: `-----BEGIN PGP SIGNATURE-----` ... `-----END PGP SIGNATURE-----` 1257 1258 **Advantages:** 1259 1. Message readable without GPG tools 1260 2. Perfect for email, forum posts, announcements 1261 3. Content and signature in single file 1262 4. Easy to copy-paste 1263 1264 **Limitations:** 1265 1. Only works with text files (not binary) 1266 2. Line endings must be preserved 1267 3. Slight size increase compared to detached signatures 1268 1269 **Use cases:** 1270 1. Email announcements and statements 1271 2. Git commit messages (when not using detached signatures) 1272 3. Forum posts and public declarations 1273 4. Security advisories 1274 5. Release notes 1275 1276 --- 1277 1278 ## Detached Signatures (Separate Signature File) 1279 1280 **Create detached binary signature:** 1281 1282 ```bash 1283 gpg --detach-sign software-package-1.2.3.tar.gz 1284 ``` 1285 1286 ```plaintext 1287 [Creates software-package-1.2.3.tar.gz.sig] 1288 ``` 1289 1290 **Create detached ASCII signature:** 1291 1292 ```bash 1293 gpg --detach-sign --armor software-package-1.2.3.tar.gz 1294 ``` 1295 1296 ```plaintext 1297 [Creates software-package-1.2.3.tar.gz.asc] 1298 ``` 1299 1300 **Detached signature content (ASCII):** 1301 1302 ```plaintext 1303 -----BEGIN PGP SIGNATURE----- 1304 1305 iQIzBAABCgAdFiEErN3xKzP4yKWaLZvzEjRWeJCrze8FAmV3GDUAC gkQEjRWeJCr 1306 ze8h9g/9FjK4pL3mN8vQ2Z... 1307 -----END PGP SIGNATURE----- 1308 ``` 1309 1310 **Sign with specific key:** 1311 1312 ```bash 1313 gpg --detach-sign --armor --local-user release@company.com product.zip 1314 ``` 1315 1316 **Verify detached signature:** 1317 1318 ```bash 1319 gpg --verify software-package-1.2.3.tar.gz.asc software-package-1.2.3.tar.gz 1320 ``` 1321 1322 ```plaintext 1323 gpg: Signature made Mon 30 Dec 2025 15:45:22 GMT 1324 gpg: using RSA key 0x1234567890ABCDEF 1325 gpg: Good signature from "John Doe (Work key) <john.doe@example.com>" [ultimate] 1326 ``` 1327 1328 **Syntax:** `gpg --detach-sign [--armor] [--local-user <key-id>] <file>` 1329 1330 | Flag | Purpose | 1331 |:--|:--| 1332 | `--detach-sign` / `-b` | Create detached signature | 1333 | `--armor` / `-a` | ASCII-armored signature | 1334 | `--local-user` / `-u` | Specify signing key | 1335 | `--output` / `-o` | Specify signature filename | 1336 1337 **How detached signatures work:** 1338 1. GPG creates hash of the entire file 1339 2. Encrypts hash with your private key 1340 3. Saves signature in separate file 1341 4. Original file remains unmodified 1342 1343 **Verification process:** 1344 1. User downloads both original file and `.sig` file 1345 2. GPG hashes the original file 1346 3. Decrypts signature with signer's public key 1347 4. Compares hashes — match = authentic 1348 1349 **Advantages:** 1350 1. Original file completely unchanged 1351 2. Works with any file type (binary, text, compressed) 1352 3. Small signature file (few KB regardless of original size) 1353 4. Standard for software distribution 1354 1355 **Use cases:** 1356 1. **Software releases**: Linux packages, tarballs, ISOs 1357 2. **Git tags**: `git tag -s v1.0.0` creates detached signature 1358 3. **Large files**: Signature stays small even for GB files 1359 4. **Multiple signatures**: Different people can sign same file 1360 1361 **Naming conventions:** 1362 1. Binary: `file.sig` 1363 2. ASCII: `file.asc` or `file.sig.asc` 1364 3. Some projects: `file.gpg` or `file.pgp` 1365 1366 --- 1367 1368 ## Combined Sign and Encrypt 1369 1370 **Sign then encrypt for recipient:** 1371 1372 ```bash 1373 gpg --sign --encrypt --recipient alice@example.com confidential-contract.pdf 1374 ``` 1375 1376 ```plaintext 1377 [Creates confidential-contract.pdf.gpg] 1378 ``` 1379 1380 **Sign and encrypt with ASCII armor:** 1381 1382 ```bash 1383 gpg -se -a -r alice@example.com sensitive-data.txt 1384 ``` 1385 1386 ```plaintext 1387 [Creates sensitive-data.txt.asc] 1388 ``` 1389 1390 **Sign and encrypt for multiple recipients:** 1391 1392 ```bash 1393 gpg -se -a -r alice@example.com -r bob@example.com -r john.doe@example.com report.txt 1394 ``` 1395 1396 **Specify signing key explicitly:** 1397 1398 ```bash 1399 gpg -s -e -a -u john.doe@example.com -r alice@example.com message.txt 1400 ``` 1401 1402 **Decrypt and verify in one step:** 1403 1404 ```bash 1405 gpg --decrypt signed-encrypted.asc 1406 ``` 1407 1408 ```plaintext 1409 gpg: encrypted with rsa4096 key, ID 0x9876543210FEDCBA, created 2025-12-30 1410 "John Doe (Work key) <john.doe@example.com>" 1411 gpg: Signature made Mon 30 Dec 2025 16:10:45 GMT 1412 gpg: using RSA key 0x1234567890ABCDEF 1413 gpg: Good signature from "Alice Smith <alice@example.com>" [full] 1414 [Decrypted message content] 1415 ``` 1416 1417 **Syntax:** `gpg --sign --encrypt --recipient <email> [--local-user <key>] <file>` 1418 1419 | Flag | Purpose | 1420 |:--|:--| 1421 | `--sign --encrypt` / `-se` | Sign then encrypt (combined) | 1422 | `--recipient` / `-r` | Specify recipients (repeatable) | 1423 | `--local-user` / `-u` | Specify signing key | 1424 | `--armor` / `-a` | ASCII-armored output | 1425 1426 **Order of operations:** 1427 1. File is **signed first** (creates signature with your private key) 1428 2. Signed data is then **encrypted** (using recipient's public key) 1429 3. Recipient must **decrypt first**, then **verify signature** 1430 1431 **Security benefits:** 1432 1. **Confidentiality**: Only recipient can read (encryption) 1433 2. **Authenticity**: Proves you sent it (signature) 1434 3. **Integrity**: Detects tampering (signature verification) 1435 4. **Non-repudiation**: You cannot deny sending (your signature) 1436 1437 **Why this is the gold standard:** 1438 1. Signing alone doesn't hide content 1439 2. Encrypting alone doesn't prove sender 1440 3. Combining both provides complete security 1441 1442 **Use cases:** 1443 1. Confidential business communications 1444 2. Legal documents requiring proof of authenticity 1445 3. Sensitive personal correspondence 1446 4. Financial information exchange 1447 1448 **Verification by recipient:** 1449 1. Decrypt with their private key (proves they're intended recipient) 1450 2. Verify signature with your public key (proves you sent it) 1451 3. Both operations happen automatically with `gpg -d` 1452 1453 --- 1454 1455 ## Verifying Signatures 1456 1457 **Verify clear-signed message:** 1458 1459 ```bash 1460 gpg --verify announcement.asc 1461 ``` 1462 1463 ```plaintext 1464 gpg: Signature made Mon 30 Dec 2025 16:30:12 GMT 1465 gpg: using RSA key 0x1234567890ABCDEF 1466 gpg: Good signature from "John Doe (Work key) <john.doe@example.com>" [ultimate] 1467 ``` 1468 1469 **Verify detached signature:** 1470 1471 ```bash 1472 gpg --verify software-1.2.3.tar.gz.asc software-1.2.3.tar.gz 1473 ``` 1474 1475 ```plaintext 1476 gpg: Signature made Mon 30 Dec 2025 16:45:00 GMT 1477 gpg: using RSA key 0x1234567890ABCDEF 1478 gpg: Good signature from "Release Team <release@company.com>" [full] 1479 ``` 1480 1481 **Verify binary signed file:** 1482 1483 ```bash 1484 gpg --verify document.gpg 1485 ``` 1486 1487 **Verify with verbose output:** 1488 1489 ```bash 1490 gpg --verify --verbose software.tar.gz.sig software.tar.gz 1491 ``` 1492 1493 **Verify and extract content:** 1494 1495 ```bash 1496 gpg --decrypt signed-message.gpg 1497 ``` 1498 1499 ```plaintext 1500 gpg: Signature made Mon 30 Dec 2025 17:00:00 GMT 1501 gpg: using RSA key 0x1234567890ABCDEF 1502 gpg: Good signature from "Alice Smith <alice@example.com>" [full] 1503 [Message content displayed] 1504 ``` 1505 1506 **Test signature creation and verification (one-liner):** 1507 1508 ```bash 1509 echo "Test message" | gpg --clearsign | gpg --verify 1510 ``` 1511 1512 ```plaintext 1513 gpg: Signature made Mon 30 Dec 2025 17:05:30 GMT 1514 gpg: using RSA key 0x1234567890ABCDEF 1515 gpg: Good signature from "John Doe (Work key) <john.doe@example.com>" [ultimate] 1516 ``` 1517 1518 **Syntax:** 1519 1. Embedded: `gpg --verify <signed-file>` 1520 2. Detached: `gpg --verify <signature-file> <original-file>` 1521 1522 | Flag | Purpose | 1523 |:--|:--| 1524 | `--verify` | Verify signature | 1525 | `--verbose` | Show detailed information | 1526 | `--status-fd N` | Machine-readable status output | 1527 1528 **Signature verification outcomes:** 1529 1530 | Message | Meaning | 1531 |:--|:--| 1532 | `Good signature` | ✅ Signature is valid and intact | 1533 | `BAD signature` | ❌ File has been tampered with or signature corrupt | 1534 | `Can't check signature: No public key` | ⚠️ You don't have signer's public key | 1535 | `Signature expired` | ⚠️ Signature was created with expired key | 1536 | `WARNING: This key is not certified` | ⚠️ You haven't verified/signed this public key | 1537 1538 **Trust indicators:** 1539 1. **[ultimate]**: Your own key 1540 2. **[full]**: You've signed this key (verified identity) 1541 3. **[marginal]**: Signed by someone you trust 1542 4. **[unknown]**: No trust relationship established 1543 5. **[expired]**: Key has passed expiration date 1544 6. **[revoked]**: Key has been revoked by owner 1545 1546 **What GPG checks:** 1547 1. Signature cryptographically matches file (integrity) 1548 2. Signature was created with private key corresponding to claimed public key (authenticity) 1549 3. Key hasn't been revoked 1550 4. Key hasn't expired (warning if expired) 1551 5. Signature timestamp (when it was created) 1552 1553 **Troubleshooting:** 1554 1. **Missing public key**: Import with `gpg --recv-keys <keyid>` or `gpg --import` 1555 2. **Untrusted key**: Verify fingerprint out-of-band, then sign: `gpg --sign-key <keyid>` 1556 3. **BAD signature**: File corrupted or tampered — do NOT trust 1557 1558 --- 1559 1560 ## Shell Aliases for Enhanced Productivity 1561 1562 **Add these to `~/.bashrc`, `~/.zshrc`, or equivalent:** 1563 1564 ```bash 1565 # Key Management 1566 alias gpg-list='gpg --list-keys --keyid-format long' 1567 alias gpg-list-secret='gpg --list-secret-keys --keyid-format long' 1568 alias gpg-fingerprint='gpg --fingerprint' 1569 alias gpg-refresh='gpg --refresh-keys' 1570 1571 # Encryption shortcuts 1572 alias gpg-encrypt='gpg -e -a -r' 1573 alias gpg-encrypt-self='gpg -e -a -r $(gpg --list-keys --keyid-format long | grep -m1 "^pub" | awk "{print \$2}" | cut -d"/" -f2)' 1574 alias gpg-symmetric='gpg -c --armor --cipher-algo AES256' 1575 1576 # Decryption 1577 alias gpg-decrypt='gpg -d' 1578 alias gpg-decrypt-file='gpg -o' 1579 1580 # Signing 1581 alias gpg-sign='gpg --clearsign' 1582 alias gpg-sign-detach='gpg -b -a' 1583 alias gpg-sign-encrypt='gpg -se -a -r' 1584 1585 # Verification 1586 alias gpg-verify='gpg --verify' 1587 1588 # Export 1589 alias gpg-export-pub='gpg --armor --export' 1590 alias gpg-export-priv='gpg --armor --export-secret-keys' 1591 1592 # Clipboard operations (macOS) 1593 alias gpg-encrypt-clip='pbpaste | gpg -e -a -r' 1594 alias gpg-decrypt-clip='pbpaste | gpg -d' 1595 alias gpg-sign-clip='pbpaste | gpg --clearsign | pbcopy' 1596 alias gpg-export-clip='gpg --armor --export $1 | pbcopy' 1597 1598 # Linux alternatives (using xclip) 1599 # alias gpg-encrypt-clip='xclip -o | gpg -e -a -r' 1600 # alias gpg-decrypt-clip='xclip -o | gpg -d' 1601 # alias gpg-sign-clip='xclip -o | gpg --clearsign | xclip -selection clipboard' 1602 1603 # Advanced operations 1604 alias gpg-revoke='gpg --gen-revoke --armor --output=revocation.asc' 1605 alias gpg-edit='gpg --edit-key' 1606 alias gpg-import='gpg --import' 1607 alias gpg-send='gpg --send-keys' 1608 alias gpg-recv='gpg --recv-keys' 1609 alias gpg-search='gpg --search-keys' 1610 1611 # Agent management 1612 alias gpg-restart='gpgconf --kill gpg-agent && gpg-agent --daemon' 1613 alias gpg-agent-status='gpg-connect-agent "getinfo version" /bye' 1614 1615 # Quick test 1616 alias gpg-test='echo "Test message" | gpg --clearsign | gpg --verify' 1617 ``` 1618 1619 **Usage examples:** 1620 1621 ```bash 1622 # Encrypt for Alice 1623 gpg-encrypt alice@example.com confidential.txt 1624 1625 # Sign and copy to clipboard 1626 echo "Important announcement" | gpg-sign-clip 1627 1628 # Decrypt clipboard content 1629 gpg-decrypt-clip 1630 1631 # Export public key to clipboard 1632 gpg-export-clip john.doe@example.com 1633 1634 # Quick signature test 1635 gpg-test 1636 ``` 1637 1638 --- 1639 1640 ## GPG Configuration Files 1641 1642 **Configuration file locations:** 1643 1644 1. `~/.gnupg/gpg.conf` — Main GPG configuration 1645 2. `~/.gnupg/gpg-agent.conf` — GPG Agent (passphrase caching, pinentry) 1646 3. `~/.gnupg/dirmngr.conf` — Directory manager (keyserver operations) 1647 4. `~/.gnupg/trustdb.gpg` — Trust database (binary, auto-managed) 1648 5. `~/.gnupg/pubring.kbx` — Public keyring (binary) 1649 6. `~/.gnupg/secring.gpg` — Secret keyring (legacy, GPG 2.1+ uses private-keys-v1.d/) 1650 1651 **Directory permissions (critical for security):** 1652 1653 ```bash 1654 chmod 700 ~/.gnupg 1655 chmod 600 ~/.gnupg/* 1656 ``` 1657 1658 --- 1659 1660 ## Recommended `~/.gnupg/gpg.conf` Configuration 1661 1662 **Production-ready configuration with security best practices:** 1663 1664 ```conf 1665 #----------------------------- 1666 # Explicit Key Selection (recommended) 1667 #----------------------------- 1668 # Prefer --local-user <FULL_FINGERPRINT> and explicit --recipient values 1669 # per command. Do not enable defaults unless their behaviour is intentional. 1670 # 1671 # Optional signing default (use a full fingerprint, never a short key ID): 1672 # default-key 0123456789ABCDEF0123456789ABCDEF01234567 1673 # 1674 # Optional automatic self-encryption. This is convenient but less explicit: 1675 # default-recipient-self 1676 # 1677 # Optional always-add recipient. This changes every encryption operation: 1678 # encrypt-to 0123456789ABCDEF0123456789ABCDEF01234567 1679 1680 #----------------------------- 1681 # Display and Output Behavior 1682 #----------------------------- 1683 # Disable copyright notice 1684 no-greeting 1685 1686 # Use long key IDs (16 hex characters) 1687 keyid-format 0xlong 1688 1689 # Display key fingerprints 1690 with-fingerprint 1691 1692 # Show UID validity when listing keys 1693 list-options show-uid-validity 1694 verify-options show-uid-validity 1695 1696 # Show key usage capabilities 1697 list-options show-usage 1698 1699 # ASCII-armored output by default (text-safe) 1700 armor 1701 1702 # Remove version string from output (privacy) 1703 no-emit-version 1704 1705 # Remove comments from output (privacy) 1706 no-comments 1707 1708 #----------------------------- 1709 # Cryptographic Preferences 1710 #----------------------------- 1711 # Preferred symmetric ciphers (strongest first) 1712 personal-cipher-preferences AES256 AES192 AES 1713 1714 # Preferred digest algorithms 1715 personal-digest-preferences SHA512 SHA384 SHA256 1716 1717 # Preferred compression algorithms 1718 personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed 1719 1720 # Default cipher for symmetric encryption 1721 cipher-algo AES256 1722 1723 # Default digest for signatures 1724 digest-algo SHA512 1725 1726 # Default compression 1727 compress-algo ZLIB 1728 1729 # Compression level (0=none, 1=fast, 9=best) 1730 compress-level 6 1731 1732 #----------------------------- 1733 # Security Hardening 1734 #----------------------------- 1735 # Disable weak algorithms 1736 disable-cipher-algo 3DES 1737 disable-cipher-algo IDEA 1738 disable-cipher-algo CAST5 1739 1740 # Mark SHA-1 as weak 1741 weak-digest SHA1 1742 1743 # Require cross-certification on subkeys 1744 require-cross-certification 1745 1746 # Don't merge user IDs on import 1747 import-options import-clean 1748 1749 # Remove unusable signatures when cleaning keys 1750 import-options import-minimal 1751 1752 #----------------------------- 1753 # Keyserver Configuration 1754 #----------------------------- 1755 # Default keyserver (modern, privacy-focused) 1756 keyserver hkps://keys.openpgp.org 1757 1758 # Alternative keyservers (uncomment if needed): 1759 # keyserver hkps://keyserver.ubuntu.com 1760 # keyserver hkps://keys.gnupg.net 1761 1762 # Automatically retrieve keys when verifying 1763 auto-key-retrieve 1764 1765 # Include revoked keys in searches 1766 keyserver-options include-revoked 1767 1768 # Don't leak key search info to keyserver 1769 keyserver-options no-honor-keyserver-url 1770 1771 #----------------------------- 1772 # User Interface 1773 #----------------------------- 1774 # Use UTF-8 for display 1775 utf8-strings 1776 1777 # Fixed list mode (parseable output) 1778 fixed-list-mode 1779 1780 # Show full timestamps 1781 list-options show-sig-expire 1782 1783 #----------------------------- 1784 # Trust and Validation 1785 #----------------------------- 1786 # Set trust model (pgp = Web of Trust, tofu = Trust On First Use) 1787 trust-model pgp 1788 1789 # Require valid certification path (stricter) 1790 # trust-model tofu+pgp 1791 1792 # Use agent for passphrases 1793 use-agent 1794 1795 # Throw keyids option (privacy - hides recipients) 1796 # throw-keyids 1797 ``` 1798 1799 **Configuration Options Explained:** 1800 1801 **Key security options:** 1802 1. **`default-recipient-self`**: Ensures you can decrypt messages you send 1803 2. **`require-cross-certification`**: Prevents fake binding signatures on subkeys 1804 3. **`weak-digest SHA1`**: Warns when SHA-1 is used (deprecated due to collisions) 1805 4. **`disable-cipher-algo 3DES`**: Prevents use of weak encryption algorithms 1806 1807 **Privacy options:** 1808 1. **`no-emit-version`**: Doesn't reveal your GPG version (reduces fingerprinting) 1809 2. **`no-comments`**: Removes comment field from output 1810 3. **`throw-keyids`**: Hides recipient key IDs (prevents traffic analysis) 1811 4. **`keyserver-options no-honor-keyserver-url`**: Ignores keyserver URLs in keys (prevents tracking) 1812 1813 **Output formatting:** 1814 1. **`armor`**: Default to ASCII output (`.asc` files) 1815 2. **`keyid-format 0xlong`**: Shows 16-character key IDs (short IDs are insecure) 1816 3. **`with-fingerprint`**: Always displays full 40-character fingerprint 1817 1818 **Algorithm preferences:** 1819 1. Listed in order of preference (strongest first) 1820 2. GPG negotiates with recipient's preferences 1821 3. Falls back to next algorithm if first isn't supported 1822 1823 --- 1824 1825 ## Recommended `~/.gnupg/gpg-agent.conf` Configuration 1826 1827 ```conf 1828 #----------------------------- 1829 # Passphrase Caching 1830 #----------------------------- 1831 # Cache passphrase for 1 hour (3600 seconds) 1832 default-cache-ttl 3600 1833 1834 # Maximum cache time: 8 hours (28800 seconds) 1835 max-cache-ttl 28800 1836 1837 # Time to cache SSH keys (if using GPG for SSH) 1838 default-cache-ttl-ssh 3600 1839 max-cache-ttl-ssh 28800 1840 1841 #----------------------------- 1842 # Pinentry (Password Prompt) 1843 #----------------------------- 1844 # Graphical pinentry (choose based on your desktop environment) 1845 1846 # For macOS: 1847 pinentry-program /usr/local/bin/pinentry-mac 1848 1849 # For GNOME/GTK: 1850 # pinentry-program /usr/bin/pinentry-gtk-2 1851 1852 # For KDE/Qt: 1853 # pinentry-program /usr/bin/pinentry-qt 1854 1855 # For terminal/console: 1856 # pinentry-program /usr/bin/pinentry-curses 1857 1858 # For TTY (servers): 1859 # pinentry-program /usr/bin/pinentry-tty 1860 1861 #----------------------------- 1862 # SSH Support 1863 #----------------------------- 1864 # Enable GPG key usage for SSH authentication 1865 enable-ssh-support 1866 1867 #----------------------------- 1868 # Security 1869 #----------------------------- 1870 # Allow passphrase entry via loopback (for scripts) 1871 allow-loopback-pinentry 1872 1873 # Enforce passphrase constraints 1874 # min-passphrase-len 20 1875 # min-passphrase-nonalpha 2 1876 1877 #----------------------------- 1878 # Logging (Debugging) 1879 #----------------------------- 1880 # Uncomment for troubleshooting 1881 # log-file /tmp/gpg-agent.log 1882 # debug-level basic 1883 # verbose 1884 ``` 1885 1886 **Apply changes:** 1887 1888 ```bash 1889 # Restart GPG agent to load new config 1890 gpgconf --kill gpg-agent 1891 gpg-agent --daemon 1892 ``` 1893 1894 --- 1895 1896 ## Recommended `~/.gnupg/dirmngr.conf` Configuration 1897 1898 ```conf 1899 #----------------------------- 1900 # Keyserver Configuration 1901 #----------------------------- 1902 # Primary keyserver 1903 keyserver hkps://keys.openpgp.org 1904 1905 # Fallback keyservers (tried if primary fails) 1906 # keyserver hkps://keyserver.ubuntu.com 1907 # keyserver hkps://pgp.mit.edu 1908 1909 #----------------------------- 1910 # Network and Proxy 1911 #----------------------------- 1912 # Honor HTTP proxy environment variables 1913 honor-http-proxy 1914 1915 # Use Tor for keyserver access (requires Tor running) 1916 # use-tor 1917 1918 # HTTP proxy (if not using environment variables) 1919 # http-proxy http://proxy.example.com:8080 1920 1921 #----------------------------- 1922 # Certificate Validation (for HKPS) 1923 #----------------------------- 1924 # Path to CA certificates (for HTTPS keyservers) 1925 # hkp-cacert /usr/share/ca-certificates/mozilla/root.crt 1926 1927 # Disable certificate checks (not recommended) 1928 # disable-http 1929 1930 #----------------------------- 1931 # Logging (Debugging) 1932 #----------------------------- 1933 # Uncomment for troubleshooting 1934 # log-file /tmp/dirmngr.log 1935 # debug-level basic 1936 # verbose 1937 ``` 1938 1939 **Apply changes:** 1940 1941 ```bash 1942 # Restart dirmngr 1943 gpgconf --kill dirmngr 1944 dirmngr --daemon 1945 ``` 1946 1947 --- 1948 1949 ## Common Troubleshooting Issues 1950 1951 **Problem: "gpg: decryption failed: No secret key"** 1952 1953 1. **Cause**: You don't have the private key needed to decrypt 1954 2. **Solution**: 1955 3. Check which key encrypted the file: `gpg --list-packets file.gpg | grep keyid` 1956 4. Verify you have that key: `gpg --list-secret-keys <keyid>` 1957 5. If missing, import backup: `gpg --import private-key-backup.asc` 1958 1959 **Problem: "gpg: WARNING: This key is not certified with a trusted signature"** 1960 1961 1. **Cause**: You haven't verified and signed the public key 1962 2. **Solution**: 1963 3. Verify fingerprint out-of-band (phone, in person) 1964 4. Sign the key: `gpg --sign-key <keyid>` 1965 5. Or adjust trust: `gpg --edit-key <keyid>` → `trust` → select level 1966 1967 **Problem: "gpg: can't connect to the agent: IPC connect call failed"** 1968 1969 1. **Cause**: GPG agent not running or socket issue 1970 2. **Solution**: 1971 ```bash 1972 # Kill existing agent 1973 gpgconf --kill gpg-agent 1974 1975 # Start new agent 1976 gpg-agent --daemon 1977 1978 # Verify it's running 1979 gpg-connect-agent 'getinfo version' /bye 1980 ``` 1981 1982 **Problem: "gpg: public key decryption failed: Inappropriate ioctl for device"** 1983 1984 1. **Cause**: Terminal not properly configured for passphrase entry 1985 2. **Solution**: 1986 ```bash 1987 export GPG_TTY=$(tty) 1988 echo "export GPG_TTY=\$(tty)" >> ~/.bashrc 1989 ``` 1990 1991 **Problem: "gpg: keyserver receive failed: No keyserver available"** 1992 1993 1. **Cause**: Keyserver configuration issue or network problem 1994 2. **Solution**: 1995 ```bash 1996 # Test keyserver connectivity 1997 gpg --keyserver hkps://keys.openpgp.org --recv-keys <keyid> 1998 1999 # Try alternative keyserver 2000 gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys <keyid> 2001 2002 # Check dirmngr status 2003 gpgconf --check-programs 2004 2005 # Restart dirmngr 2006 gpgconf --kill dirmngr 2007 ``` 2008 2009 **Problem: "gpg: signing failed: Unusable secret key"** 2010 2011 1. **Cause**: Key expired or passphrase wrong 2012 2. **Solution**: 2013 ```bash 2014 # Check key expiration 2015 gpg --list-keys <keyid> 2016 2017 # Extend expiration 2018 gpg --edit-key <keyid> 2019 # In editor: expire → set new date → save 2020 2021 # Upload updated key 2022 gpg --send-keys <keyid> 2023 ``` 2024 2025 **Problem: Permission errors on `~/.gnupg`** 2026 2027 1. **Cause**: Incorrect file permissions (GPG requires strict permissions) 2028 2. **Solution**: 2029 ```bash 2030 chmod 700 ~/.gnupg 2031 chmod 600 ~/.gnupg/* 2032 chmod 700 ~/.gnupg/private-keys-v1.d 2033 ``` 2034 2035 **Problem: "gpg: Fatal: can't create directory"** 2036 2037 1. **Cause**: GPG directory doesn't exist or ownership wrong 2038 2. **Solution**: 2039 ```bash 2040 mkdir -p ~/.gnupg 2041 chmod 700 ~/.gnupg 2042 chown -R $USER:$USER ~/.gnupg 2043 ``` 2044 2045 --- 2046 2047 ## Diagnostic Commands 2048 2049 **Check GPG version and capabilities:** 2050 2051 ```bash 2052 gpg --version 2053 ``` 2054 2055 ```plaintext 2056 gpg (GnuPG) 2.4.0 2057 libgcrypt 1.10.1 2058 Supported algorithms: 2059 Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA 2060 Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, 2061 CAMELLIA128, CAMELLIA192, CAMELLIA256 2062 Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 2063 Compression: Uncompressed, ZIP, ZLIB, BZIP2 2064 ``` 2065 2066 **List loaded configuration options:** 2067 2068 ```bash 2069 gpg --list-config 2070 ``` 2071 2072 **Check agent status:** 2073 2074 ```bash 2075 gpg-connect-agent 'getinfo version' /bye 2076 ``` 2077 2078 ```plaintext 2079 D 2.4.0 2080 OK 2081 ``` 2082 2083 **Test key with verbose output:** 2084 2085 ```bash 2086 gpg -vvv --list-keys john.doe@example.com 2087 ``` 2088 2089 **Update trust database:** 2090 2091 ```bash 2092 gpg --update-trustdb 2093 ``` 2094 2095 **Check trust database integrity:** 2096 2097 ```bash 2098 gpg --check-trustdb 2099 ``` 2100 2101 **List all GPG-related processes:** 2102 2103 ```bash 2104 ps aux | grep gpg 2105 ``` 2106 2107 **Force passphrase re-entry (clear cache):** 2108 2109 ```bash 2110 echo RELOADAGENT | gpg-connect-agent 2111 ``` 2112 2113 **Restart all GPG components:** 2114 2115 ```bash 2116 gpgconf --kill all 2117 gpg-agent --daemon 2118 ``` 2119 2120 --- 2121 2122 ## Hardware Token Integration (YubiKey, Nitrokey) 2123 2124 **Why use hardware tokens:** 2125 2126 1. **Private keys never leave the device** — cannot be copied or exfiltrated 2127 2. **Physical presence required** — protection against remote attacks 2128 3. **PIN protection** — additional authentication layer 2129 4. **Tamper-resistant** — specialized security chips 2130 5. **Portable** — use your keys on multiple computers without copying them 2131 2132 **Supported operations:** 2133 2134 1. Store GPG signing subkey 2135 2. Store GPG encryption subkey 2136 3. Store GPG authentication subkey (for SSH) 2137 4. Store master key (advanced: offline master key setup) 2138 2139 **Check if token is detected:** 2140 2141 ```bash 2142 gpg --card-status 2143 ``` 2144 2145 ```plaintext 2146 Reader: Yubico YubiKey OTP+FIDO+CCID 2147 Application ID: D2760001240100000006123456780000 2148 Version: 3.4 2149 Manufacturer: Yubico 2150 Serial number: 12345678 2151 Name of cardholder: John Doe 2152 Language prefs: en 2153 Sex: male 2154 URL of public key: https://example.com/john-doe.asc 2155 Login data: john.doe@example.com 2156 Signature PIN: not forced 2157 Key attributes: rsa4096 rsa4096 rsa4096 2158 Max. PIN lengths: 127 127 127 2159 PIN retry counter: 3 0 3 2160 Signature counter: 42 2161 Signature key: ABCD EF12 3456 7890 2162 created: 2025-12-30 2163 Encryption key: 1234 5678 90AB CDEF 2164 created: 2025-12-30 2165 Authentication key: 9876 5432 10FE DCBA 2166 created: 2025-12-30 2167 ``` 2168 2169 **Move existing subkey to token:** 2170 2171 ```bash 2172 gpg --edit-key john.doe@example.com 2173 # In editor: 2174 key 1 # Select signing subkey 2175 keytocard # Move to card 2176 # Choose slot (1=signature, 2=encryption, 3=authentication) 2177 save 2178 ``` 2179 2180 **Generate key directly on token (cannot be backed up):** 2181 2182 ```bash 2183 gpg --card-edit 2184 # In editor: 2185 admin 2186 generate 2187 # Follow prompts 2188 ``` 2189 2190 **Hardware Token Backup Strategy:** 2191 2192 1. **Keys moved to hardware tokens cannot be extracted** — this is by design 2193 2. **Always keep encrypted backup of private keys** before moving to hardware 2194 3. **Consider having two tokens** with identical keys for redundancy 2195 4. **Store revocation certificate offline** in case token is lost 2196 5. **Document your PINs securely** (default Admin PIN: 12345678, User PIN: 123456) 2197 6. **Backup strategy**: 2198 7. Export subkeys before moving: `gpg --armor --export-secret-subkeys <keyid>` 2199 8. Store on encrypted USB drive in safe location 2200 9. Test restoration process periodically 2201 2202 --- 2203 2204 ## Using GPG for SSH Authentication 2205 2206 **Why use GPG for SSH:** 2207 2208 1. Single key for both GPG and SSH operations 2209 2. Hardware token support (YubiKey, Nitrokey) 2210 3. Centralized key management 2211 4. Subkey rotation without changing SSH configuration 2212 2213 **Setup process:** 2214 2215 1. **Enable SSH support in `gpg-agent.conf`:** 2216 2217 ```bash 2218 echo "enable-ssh-support" >> ~/.gnupg/gpg-agent.conf 2219 gpgconf --kill gpg-agent 2220 ``` 2221 2222 2. **Configure shell environment:** 2223 2224 ```bash 2225 # Add to ~/.bashrc or ~/.zshrc 2226 export GPG_TTY=$(tty) 2227 export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) 2228 gpgconf --launch gpg-agent 2229 ``` 2230 2231 3. **Create authentication subkey (if you don't have one):** 2232 2233 ```bash 2234 gpg --expert --edit-key john.doe@example.com 2235 # In editor: 2236 addkey 2237 # Choose: (8) RSA (set your own capabilities) 2238 # Toggle: S, E (to disable), toggle A (to enable authentication) 2239 # Choose key size: 4096 2240 # Choose expiration: 1y 2241 save 2242 ``` 2243 2244 4. **Add authentication subkey to SSH:** 2245 2246 ```bash 2247 # Get authentication subkey keygrip 2248 gpg --list-keys --with-keygrip john.doe@example.com 2249 2250 # Add keygrip to sshcontrol 2251 echo "YOUR_KEYGRIP_HERE" >> ~/.gnupg/sshcontrol 2252 ``` 2253 2254 5. **Export SSH public key:** 2255 2256 ```bash 2257 gpg --export-ssh-key john.doe@example.com 2258 ``` 2259 2260 ```plaintext 2261 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC... openpgp:0xABCDEF12 2262 ``` 2263 2264 6. **Add to remote server:** 2265 2266 ```bash 2267 gpg --export-ssh-key john.doe@example.com >> ~/.ssh/authorized_keys 2268 # Or copy-paste to remote server's ~/.ssh/authorized_keys 2269 ``` 2270 2271 7. **Test SSH connection:** 2272 2273 ```bash 2274 ssh user@remote-server.com 2275 # Should prompt for GPG passphrase (or PIN if using hardware token) 2276 ``` 2277 2278 --- 2279 2280 ## Advanced Key Management: Master Key Offline Strategy 2281 2282 **Concept:** 2283 2284 1. Keep master key on air-gapped machine or hardware token 2285 2. Use subkeys for daily operations 2286 3. If subkey compromised, revoke only subkey, not entire identity 2287 2288 **Implementation:** 2289 2290 1. **Generate master key on air-gapped machine:** 2291 2292 ```bash 2293 gpg --expert --full-generate-key 2294 # Choose: (1) RSA and RSA 2295 # Size: 4096 2296 # Capabilities: Certify only (disable Sign and Encrypt) 2297 # Expiry: 0 (does not expire) 2298 ``` 2299 2300 2. **Add subkeys for daily use:** 2301 2302 ```bash 2303 gpg --expert --edit-key <master-key-id> 2304 # Add signing subkey: 2305 addkey → (4) RSA (sign only) → 4096 → 1y → save 2306 2307 # Add encryption subkey: 2308 addkey → (6) RSA (encrypt only) → 4096 → 1y → save 2309 2310 # Add authentication subkey: 2311 addkey → (8) RSA (set capabilities) → toggle all except A → 4096 → 1y → save 2312 ``` 2313 2314 3. **Backup master key:** 2315 2316 ```bash 2317 gpg --armor --export-secret-keys <master-key-id> > master-key-backup.asc 2318 gpg --armor --export-secret-subkeys <master-key-id> > subkeys-backup.asc 2319 gpg --gen-revoke --output revocation.asc <master-key-id> 2320 2321 # Store on encrypted USB drives (multiple copies) 2322 # Consider paper backup with paperkey 2323 ``` 2324 2325 4. **Export subkeys for daily machine:** 2326 2327 ```bash 2328 gpg --armor --export-secret-subkeys <master-key-id> > daily-subkeys.asc 2329 ``` 2330 2331 5. **On daily machine, delete master key (keep subkeys):** 2332 2333 ```bash 2334 # Import subkeys 2335 gpg --import daily-subkeys.asc 2336 2337 # Verify you have subkeys 2338 gpg --list-secret-keys 2339 # You should see "sec#" (hash indicates master key stub only) 2340 ``` 2341 2342 6. **Annual subkey rotation (requires master key):** 2343 2344 ```bash 2345 # On air-gapped machine with master key: 2346 gpg --edit-key <master-key-id> 2347 key 1 # Select old subkey 2348 expire # Extend or revoke 2349 addkey # Create new subkey 2350 save 2351 2352 # Export updated subkeys to daily machine 2353 ``` 2354 2355 --- 2356 2357 ## References and Further Reading 2358 2359 **Official Documentation:** 2360 1. [GnuPG Official Website](https://gnupg.org/) — Primary resource for GPG 2361 2. [GnuPG Manual](https://gnupg.org/documentation/manuals/gnupg/) — Comprehensive reference guide 2362 3. [RFC 4880 - OpenPGP Message Format](https://www.rfc-editor.org/rfc/rfc4880) — Protocol specification 2363 4. [GnuPG FAQ](https://gnupg.org/faq/gnupg-faq.html) — Common questions and answers 2364 2365 **Security and Best Practices:** 2366 1. [OpenPGP Best Practices](https://riseup.net/en/security/message-security/openpgp/best-practices) — Riseup security collective recommendations 2367 2. [Debian Wiki: Using OpenPGP subkeys](https://wiki.debian.org/Subkeys) — Advanced key management 2368 3. [Creating the Perfect GPG Keypair](https://alexcabal.com/creating-the-perfect-gpg-keypair) — Detailed walkthrough 2369 4. [The GNU Privacy Handbook](https://gnupg.org/gph/en/manual.html) — Beginner-friendly guide 2370 2371 **Hardware Token Resources:** 2372 1. [YubiKey GPG Guide](https://support.yubico.com/hc/en-us/articles/360013790259-Using-Your-YubiKey-with-OpenPGP) — Official YubiKey documentation 2373 2. [Nitrokey Documentation](https://docs.nitrokey.com/) — Nitrokey Pro and Storage setup 2374 3. [drduh's YubiKey Guide](https://github.com/drduh/YubiKey-Guide) — Comprehensive hardware token tutorial 2375 2376 **Cryptographic Background:** 2377 1. [Public-Key Cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography) — Wikipedia overview 2378 2. [Digital Signature](https://en.wikipedia.org/wiki/Digital_signature) — Cryptographic signature concepts 2379 3. [Web of Trust](https://en.wikipedia.org/wiki/Web_of_trust) — Trust model explanation 2380 4. [Curve25519](https://en.wikipedia.org/wiki/Curve25519) — Modern elliptic curve cryptography 2381 2382 **Practical Guides:** 2383 1. [Using GPG for Email](https://emailselfdefense.fsf.org/en/) — FSF Email Self-Defense guide 2384 2. [Git Commit Signing](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work) — Signing commits and tags 2385 3. [Pass: The Standard Unix Password Manager](https://www.passwordstore.org/) — GPG-based password manager 2386 2387 **Keyserver Information:** 2388 1. [keys.openpgp.org](https://keys.openpgp.org/) — Modern, privacy-focused keyserver 2389 2. [Ubuntu Keyserver](https://keyserver.ubuntu.com/) — Popular keyserver pool 2390 3. [SKS Keyserver Status](https://sks-keyservers.net/status/) — Legacy SKS network (deprecated) 2391 2392 **Community and Support:** 2393 1. [GnuPG Mailing Lists](https://gnupg.org/documentation/mailing-lists.html) — Official support channels 2394 2. [r/GnuPG](https://www.reddit.com/r/GnuPG/) — Reddit community 2395 3. [Stack Exchange: Cryptography](https://crypto.stackexchange.com/) — Q&A for cryptographic topics 2396 2397 --- 2398 2399 #Cryptography #GnuPG #GPG #Encryption #Digital-Signatures #OpenPGP #Key-Management #Public-Key-Cryptography #Privacy #Security #PGP #Asymmetric-Encryption #Symmetric-Encryption #Web-of-Trust #Command-Line #Linux #macOS #BSD #PKI #Ed25519 #RSA #AES #SHA512 #Keyserver #YubiKey #Hardware-Token #SSH-Authentication #Email-Encryption #Code-Signing #File-Security