top of page

How To Send Messages Using PGP Encryption (Guide)

How To Send Messages Using PGP Encryption (Guide) | Black Hat HQ

How To Send Messages Using PGP Encryption


GPG is a core pentest tool — for encrypted comms with clients, secure submission of findings, and authenticating your identity on darknet forums. Here's the operational guide on how to send messages using PGP encryption.


The GPG Model


GPG uses asymmetric encryption:


Your private key (secret) → decrypts messages sent TO you, signs messages FROM you
Your public key (shared)  → encrypts messages TO you, verifies signatures FROM you

Private key stays on your air-gapped machine. Public key goes everywhere — your email signature, your website, keyservers, forum profiles. Anyone can send you an encrypted message that only you can read.


Step 1: Generate Your Keypair


Standard Generation (RSA 4096)


bash

gpg --full-generate-key

Walk through the prompts:


Please select what kind of key you want:
   (1) RSA and RSA (default)
   (9) ECC and ECC
Your selection? 9       # ECC is modern, faster, smaller keys

Please select which elliptic curve you want:
   (1) Curve 25519       # Best choice for most uses
Your selection? 1

Please specify how long the key should be valid.
   0 = key does not expire
   1y = 1 year (recommended — you can extend later)
Your selection? 1y

Real name: [Your pentest alias or real name, depending on context]
Email address: alias@proton.me    # Your burner or work email
Comment: Pentesting key 2026

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

# You'll be prompted for a passphrase.
# THIS IS CRITICAL. The passphrase encrypts your private key on disk.
# Without it, anyone who steals your private key file can impersonate you.

# Minimum: 6-word Diceware passphrase
# Better: 8+ words
# Write it down. Store it separately from the key.

Alternative: RSA 4096 (Wider Compatibility)


bash

gpg --full-generate-key
# Select (1) RSA and RSA
# Keysize: 4096
# Expiry: 1y

RSA 4096 is universally compatible. ECC (Curve 25519) is faster and smaller but some older GPG implementations don't support it. For pentesting in 2026, ECC is fine — everything modern supports it.


Verify Your Key


bash

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

# Output looks like:
# sec   ed25519 2026-07-04 [SC] [expires: 2027-07-04]
#       AB12CD34EF56AB12CD34EF56AB12CD34EF56AB12
# uid           [ultimate] Pentest Alias <alias@proton.me>
# ssb   cv25519 2026-07-04 [E] [expires: 2027-07-04]

# The fingerprint is the long hex string.
# The key ID is the last 16 characters: EF56AB12CD34EF56

Generate a Revocation Certificate (Do This Now)


bash

gpg --output revocation.asc --gen-revoke AB12CD34EF56AB12

The revocation certificate lets you declare your key compromised. Store this offline — printed on paper in a safe, or on an air-gapped USB. If your key is ever lost or stolen, you publish this certificate and clients know to stop trusting it.

Without the revocation certificate, a compromised key haunts you forever.


Step 2: Export and Share Your Public Key


bash

# Export public key (ASCII-armored, shareable)
gpg --armor --export alias@proton.me > my_public_key.asc

# Or directly to keyserver
gpg --keyserver keys.openpgp.org --send-keys AB12CD34EF56AB12

The public key looks like:


-----BEGIN PGP PUBLIC KEY BLOCK-----

mDMEXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
... many lines of base64 ...
-----END PGP PUBLIC KEY BLOCK-----

Share this everywhere you want to receive encrypted messages:


  • Email signature

  • Website / GitHub profile

  • Darknet forum profile

  • Pentest report contact page

  • Business cards (QR code)


Export Your Private Key (For Backup)


bash

# Export private key — GUARD THIS WITH YOUR LIFE
gpg --armor --export-secret-keys alias@proton.me > my_private_key.asc

# Store on air-gapped USB
# Store printed paper copy in a safe
# Never on cloud storage
# Never on a network-connected machine

Step 3: Encrypting A Message


Encrypt for a Specific Recipient


bash

# You need the recipient's public key first
gpg --import recipient_public_key.asc
# Or fetch from keyserver:
gpg --keyserver keys.openpgp.org --search-keys recipient@example.com

# Verify the key fingerprint with the recipient (out of band — Signal, phone, in person)
gpg --fingerprint recipient@example.com

# Sign their key if you've verified it:
gpg --sign-key recipient@example.com

# Now encrypt a message
echo "Sensitive findings from today's engagement" | \
  gpg --encrypt --armor --recipient recipient@example.com > encrypted.asc

Encrypt with a Password Instead of a Key (Symmetric)


For files you want to encrypt with a shared passphrase (no keypair needed):

bash

# Encrypt
gpg --symmetric --armor findings.txt
# Prompts for passphrase (enter twice)
# Outputs: findings.txt.asc

# Decrypt (anyone with the passphrase)
gpg --decrypt findings.txt.asc > findings.txt

Encrypt a File for Multiple Recipients


bash

gpg --encrypt --armor \
  --recipient client_cto@company.com \
  --recipient client_ciso@company.com \
  --recipient alias@proton.me \
  pentest_report.pdf

# Output: pentest_report.pdf.asc
# All three recipients can decrypt it

Encrypt and Sign (Prove It's From You)


bash

# Encrypt AND sign — recipient knows it's from you and hasn't been tampered with
gpg --encrypt --sign --armor --recipient client@company.com message.txt

Step 4: Decrypting A Message


bash

# Decrypt
gpg --decrypt encrypted.asc

# If it's signed, GPG will verify the signature automatically
# Output shows:
# gpg: Signature made Sat 04 Jul 2026 09:15:00 AM UTC
# gpg:                using EDDSA key AB12CD34EF56AB12
# gpg: Good signature from "Pentest Alias <alias@proton.me>"

# Decrypt to file
gpg --decrypt encrypted.asc > plaintext.txt

Step 5: Signing (Without Encryption)


For files that need integrity verification but not secrecy:


bash

# Create a detached signature
gpg --detach-sign --armor pentest_report.pdf
# Creates: pentest_report.pdf.asc (signature file)

# Recipient verifies:
gpg --verify pentest_report.pdf.asc pentest_report.pdf
# Output: "Good signature from..." if valid

# Clear-sign (signature embedded in the file, readable without GPG)
gpg --clearsign message.txt
# Creates: message.txt.asc
# Contains the plaintext + signature block
# Anyone can read the message; GPG users can verify it

Pentest Use Cases


1. Secure Client Communication


bash

# Client sends you their public key
# You import it, verify fingerprint (Signal/phone call)
gpg --import client_key.asc
gpg --fingerprint client@company.com
# "I'm reading the fingerprint: AB12 CD34 EF56... Did you get the same?"

# Now all findings, credentials, and sensitive data go encrypted:
cat initial_findings.txt | gpg --encrypt --armor --sign \
  --recipient client@company.com > findings.gpg

# Send findings.gpg over email/Slack/whatever — it's safe

2. Final Report Delivery


bash

# Encrypt the full pentest report
gpg --encrypt --sign --armor \
  --recipient client_cto@company.com \
  --recipient client_pm@company.com \
  final_report.pdf

# Also provide a SHA256 checksum of the encrypted file
sha256sum final_report.pdf.asc > final_report.pdf.asc.sha256

3. Darknet Communications


For the darknet research you asked about earlier:


bash

# Generate a dedicated keypair for darknet use
# Use your darknet alias ONLY
# Use a burner email (ProtonMail onion signup)
# Generate on Tails — the key never touches a clearnet machine

# Export the public key
gpg --armor --export darknet_alias@proton.me > darknet_pub.asc

# Post this public key on your forum profile
# Vendors, researchers, and contacts encrypt messages to you
# You decrypt them on Tails, offline

# CRITICAL: Never mix darknet key with your real identity key
# A cross-signature or shared UID on a keyserver links both identities

4. Encrypted Data Exfiltration (Post-Exploitation)


bash

# On the compromised host:
# Encrypt loot with your public key (which you've pre-loaded)
gpg --encrypt --recipient pentest@proton.me collected_data.tar.gz

# The encrypted file is now safe to exfiltrate
# Even if intercepted, only you can decrypt it
# The target's DLP can't inspect the contents

# For added stealth: encrypt to a key that's only on your
# air-gapped machine — not associated with your engagement

5. Dead Man's Switch


bash

# Encrypt a message to yourself with a future date
# Give the passphrase to a trusted party with instructions:
# "If I don't reset this by DATE, publish the passphrase"

# Or use GPG + timed release:
# 1. Generate a one-time keypair
# 2. Encrypt the findings with it
# 3. Encrypt the private key with a passphrase
# 4. Give the passphrase to your dead man's switch service
# 5. If you don't check in, the passphrase is released
# 6. Anyone can now decrypt the private key and then the findings

Key Management for Pentesters


Separate Keys for Separate Contexts


bash

# Generate distinct keys:
# Key 1: Professional pentesting (alias@company.com)
# Key 2: Darknet research (darknet_alias@proton.me)
# Key 3: Personal (realname@personal.com)
# Key 4: Per-engagement throwaway key

# NEVER cross-sign these keys
# NEVER list multiple UIDs on the same key
# Keyservers permanently link cross-signed identities

Extending an Expiring Key


bash

# Check expiry
gpg --list-keys alias@proton.me

# Extend by 1 year
gpg --quick-set-expire AB12CD34EF56AB12 1y

# Then re-publish the updated public key
gpg --keyserver keys.openpgp.org --send-keys AB12CD34EF56AB12

Rotating Keys After an Engagement


bash

# 1. Generate new key
gpg --full-generate-key

# 2. Sign the new key with the old key (transition statement)
gpg --sign-key NEW_KEY_ID

# 3. Export the transition statement
gpg --armor --export NEW_KEY_ID > transition.asc

# 4. Revoke the old key (if compromised or retiring)
gpg --import revocation.asc   # Your pre-generated revocation cert
gpg --keyserver keys.openpgp.org --send-keys OLD_KEY_ID

# 5. Publish the new key
gpg --keyserver keys.openpgp.org --send-keys NEW_KEY_ID

Tails + GPG Workflow


For darknet or high-sensitivity work on Tails:


bash

# Tails has GPG built in. The workflow:

# 1. Boot Tails with Persistent Storage enabled
#    Applications → Tails → Persistent Storage
#    Enable: GnuPG

# 2. Generate or import keys
gpg --full-generate-key
# The private key is stored in the encrypted persistent volume

# 3. Use Tails' GPG applet (top-right clipboard icon)
#    Copy encrypted text → click applet → Decrypt/Verify
#    Type message → click applet → Sign/Encrypt

# 4. The persistent GPG keyring survives reboots
#    Everything else is wiped

# 5. For maximum OPSEC: DON'T use persistent storage
#    Generate a fresh key each session
#    Publish the public key immediately
#    The private key dies when you shut down
#    This is extreme but eliminates the risk of key seizure

Common Mistakes


Mistake

Why It Matters

Not verifying fingerprints out-of-band

MITM: someone replaces the public key on the keyserver, you encrypt to the attacker

Using the same key for darknet + real identity

Keyserver linkage = permanent de-anonymization

Private key on a networked machine

Malware steals the key file + passphrase via keylogger

Password reuse for GPG passphrase

Database breach at one site → attacker cracks your GPG passphrase

Publishing to keyservers with real email

Keyservers are permanent and public. Your real email is now linked to your key forever.

Forgetting the passphrase

No recovery. The key is lost. Generate revocation certs BEFORE you forget.

Not generating a revocation certificate

Key compromise = permanent. You can never revoke it.

Short passphrase

"hunter2" cracks in seconds. Minimum 6-word Diceware.

Expiry set to "never"

If you lose access to the key, there's no automatic fallback. Set 1-2 year expiry.


Quick Reference Card


bash

# GENERATE
gpg --full-generate-key                          # New keypair
gpg --output revocation.asc --gen-revoke KEYID   # Revocation cert

# EXPORT
gpg --armor --export user@domain.com > pub.asc   # Public key
gpg --armor --export-secret-keys user > sec.asc  # Private key (GUARD)

# IMPORT
gpg --import someone_pub.asc                     # Their public key
gpg --fingerprint user@domain.com                # Verify fingerprint

# ENCRYPT
gpg --encrypt --armor -r recipient file.txt      # Encrypt for them
gpg --symmetric --armor file.txt                 # Encrypt with password
gpg --encrypt --sign --armor -r recip file.txt   # Encrypt + sign

# DECRYPT
gpg --decrypt encrypted.asc                      # Decrypt to stdout
gpg --decrypt encrypted.asc > output.txt         # Decrypt to file

# SIGN
gpg --detach-sign --armor file.pdf               # Detached signature
gpg --clearsign message.txt                      # Clear-sign

# VERIFY
gpg --verify file.pdf.asc file.pdf               # Verify signature

# KEY MANAGEMENT
gpg --list-keys                                  # Public keys
gpg --list-secret-keys                           # Private keys
gpg --quick-set-expire KEYID 1y                  # Extend expiry
gpg --keyserver keys.openpgp.org --send-keys KEYID  # Publish
gpg --keyserver keys.openpgp.org --search-keys user   # Search

Enroll In Online Cybersecurity & Hacking Classes/Courses | Black Hat HQ

Comments


bottom of page