Skip to content
The Security Editor

Encryption

Tar, encrypt, upload: using GPG to secure files before they hit the cloud

A no-nonsense tutorial on using GnuPG to encrypt files before they leave your machine. Works with any cloud provider, requires no new service, and keeps you in control of the keys. Plus when this is the right tool and when it isn't.

By Alex Trustwell 7 min read intermediate
On this page
  1. Install GPG
  2. Choose: symmetric or public-key?
  3. The core workflow: tar, encrypt, upload
  4. Step 1: tar the directory
  5. Step 2: encrypt
  6. Step 3: verify and clean up
  7. Step 4: upload
  8. Step 5: decrypt (later, or on another machine)
  9. Scripting it for routine use
  10. The public-key variant
  11. Generate a key pair (once per person)
  12. Share your public key
  13. Import the recipient’s public key
  14. Encrypt for the recipient
  15. Decrypt (on the recipient’s side)
  16. When this is the right tool
  17. When it’s not the right tool
  18. A few gotchas worth knowing

GPG (GnuPG, the open implementation of the OpenPGP standard) is not the first tool a new user should reach for. It is command-line, it has a reputation for bad ergonomics, and for most consumer use cases a purpose-built tool like Cryptomator is a better fit.

But GPG is still the right tool for a specific, important job: taking a directory of files, turning it into a single encrypted archive, and uploading that archive to any cloud provider (or sending it through any transport) without the provider being able to read the contents. If you want client-side encryption that doesn’t depend on a specific vendor’s software and will still work in ten years, GPG is the correct answer.

This article walks through the workflow end to end.

Install GPG

macOS:

brew install gnupg

Windows (PowerShell):

winget install --id GnuPG.Gpg4win -e

Gpg4win installs GPG plus a GUI (Kleopatra) and integrations with Windows Explorer. The command-line gpg is available in a new terminal after install.

Linux:

sudo apt install gnupg          # Debian/Ubuntu
sudo dnf install gnupg2         # Fedora

Verify:

gpg --version

You want version 2.2 or newer. Older 1.x versions are end-of-life.

Choose: symmetric or public-key?

GPG can encrypt in two fundamentally different ways, and most tutorials blur the distinction. Pick on purpose:

  • Symmetric encryption — one passphrase encrypts and decrypts. Great for encrypting files for yourself (archival, cloud backup, offline storage). The only secret is the passphrase.
  • Public-key encryption — you encrypt to someone using their public key; they decrypt with their private key. Great for sending files to other people. Requires key management on both sides.

For “encrypt before uploading to Dropbox”, you almost always want symmetric. You are the sender and the recipient. A passphrase is simpler and has fewer ways to go wrong.

For “send a file to my lawyer who also uses GPG”, you want public-key. Harder to set up; the right tool for the job.

The rest of this guide covers symmetric first, then covers public-key at the end.

The core workflow: tar, encrypt, upload

Step 1: tar the directory

tar (tape archive) bundles a directory into a single file. Most backup and transport tools work better with one file than with a thousand.

cd /path/to/parent
tar -cf ~/sensitive-docs.tar ./sensitive-docs

Flags used:

  • -c create an archive
  • -f specifies the archive filename

For smaller output, add compression. gzip is universal, zstd is faster and smaller if both ends have modern tar:

tar -czf ~/sensitive-docs.tar.gz ./sensitive-docs     # gzip
tar --zstd -cf ~/sensitive-docs.tar.zst ./sensitive-docs  # zstd

Compression is applied before encryption, which is correct — ciphertext is incompressible, so compressing the plaintext is the only useful order.

Step 2: encrypt

gpg --symmetric \
    --cipher-algo AES256 \
    --s2k-mode 3 \
    --s2k-digest-algo SHA512 \
    --s2k-count 65011712 \
    --output ~/sensitive-docs.tar.gz.gpg \
    ~/sensitive-docs.tar.gz

What each flag does:

  • --symmetric — passphrase-based encryption (as opposed to public-key).
  • --cipher-algo AES256 — AES with a 256-bit key. Default varies by GPG version; making it explicit is good hygiene.
  • --s2k-mode 3 — iterated+salted passphrase-to-key derivation (S2K). Protects against brute-force of the passphrase.
  • --s2k-digest-algo SHA512 — stronger hash than the default.
  • --s2k-count 65011712 — high iteration count; slows brute-force attempts on the passphrase. (65011712 is the maximum; slower to unlock but much harder to attack.)
  • --output — the encrypted output file.

GPG will prompt for a passphrase. Use a strong one. A 5+ word Diceware-style passphrase or a 16+ character random string from your password manager. Anything weaker is the limiting factor in the whole setup.

Step 3: verify and clean up

Verify the encrypted file exists and the plaintext tarball can be removed:

ls -lh ~/sensitive-docs.tar.gz.gpg
gpg --list-packets ~/sensitive-docs.tar.gz.gpg | head
rm ~/sensitive-docs.tar.gz    # plaintext tarball, no longer needed

The --list-packets output confirms the file is a GPG-encrypted blob and shows which cipher was used. If it doesn’t say AES256, check your flags.

Then delete the source plaintext if you want to — for archival scenarios, you usually keep the original working copy somewhere controlled and hand only the encrypted blob to the cloud.

Step 4: upload

# Any of these works — the encrypted file is opaque to all of them.
aws s3 cp ~/sensitive-docs.tar.gz.gpg s3://my-bucket/sensitive/
rclone copy ~/sensitive-docs.tar.gz.gpg remote:Dropbox/encrypted/
cp ~/sensitive-docs.tar.gz.gpg ~/Dropbox/    # Dropbox sync picks it up

The provider sees ciphertext. They don’t know what’s in it, they can’t search it, they can’t preview it.

Step 5: decrypt (later, or on another machine)

gpg --output ~/sensitive-docs.tar.gz --decrypt ~/sensitive-docs.tar.gz.gpg
tar -xzf ~/sensitive-docs.tar.gz

GPG prompts for the passphrase, writes the plaintext tarball, then tar extracts. You now have the original directory back.

Scripting it for routine use

If you do this often, wrap it:

#!/usr/bin/env bash
# encrypt-upload.sh <source-dir> <s3-path>
set -euo pipefail

SRC="$1"
DEST="$2"
TMP="$(mktemp -d)"
NAME="$(basename "$SRC")-$(date +%Y%m%d-%H%M%S)"

echo "==> Taring $SRC..."
tar -czf "$TMP/$NAME.tar.gz" -C "$(dirname "$SRC")" "$(basename "$SRC")"

echo "==> Encrypting..."
gpg --symmetric \
    --cipher-algo AES256 \
    --s2k-mode 3 \
    --s2k-digest-algo SHA512 \
    --s2k-count 65011712 \
    --output "$TMP/$NAME.tar.gz.gpg" \
    "$TMP/$NAME.tar.gz"

echo "==> Uploading to $DEST..."
aws s3 cp "$TMP/$NAME.tar.gz.gpg" "$DEST/$NAME.tar.gz.gpg"

echo "==> Cleaning up..."
rm -rf "$TMP"

echo "==> Done: $DEST/$NAME.tar.gz.gpg"

Save as encrypt-upload.sh, make executable (chmod +x), and run:

./encrypt-upload.sh ~/Documents/Taxes s3://my-backups/taxes

Each invocation produces a dated archive. GPG will prompt for the passphrase on each run; for unattended use see the passphrase-in-file options in the GPG manual (but understand the tradeoff — a stored passphrase reduces the protection).

The public-key variant

For sending files to someone else, symmetric is wrong; you don’t want to send the passphrase through the same channel as the file. Public-key encryption solves this:

Generate a key pair (once per person)

gpg --full-generate-key

Choose:

  • Key type: ECC (sign and encrypt) (modern default — Curve 25519). Alternatively RSA and RSA with 4096-bit keys for maximum compatibility.
  • Expiration: pick something — “never” is a bad habit. 2–5 years is reasonable; you can extend later.
  • Real name and email: identifies the key. The email doesn’t have to be your real one.

Share your public key

gpg --armor --export you@example.com > you.asc

Publish you.asc somewhere the recipient can fetch it — your website, a keyserver, or just email it. Your private key never leaves your machine.

Import the recipient’s public key

gpg --import lawyer.asc
gpg --list-keys

Verify the fingerprint by calling them or meeting in person. The fingerprint is a unique identifier of the public key:

gpg --fingerprint lawyer@example.com

Compare the printed fingerprint with the one they read out loud. This one-time verification is what prevents a man-in-the-middle from substituting their own key.

Encrypt for the recipient

gpg --encrypt --armor --recipient lawyer@example.com document.pdf

Produces document.pdf.asc (ASCII-armored) or document.pdf.gpg (binary, without --armor). Either can be emailed, dropped in a shared folder, or sent through any channel — only the recipient’s private key can decrypt it.

Decrypt (on the recipient’s side)

gpg --decrypt document.pdf.asc > document.pdf

GPG uses their private key automatically if it’s in their keyring.

When this is the right tool

GPG is the right choice when you need:

  • Long-term archival. .tar.gz.gpg files written today will be readable in twenty years with standard tools. No vendor lock-in.
  • Provider independence. The encrypted blob is portable. Move between AWS, Backblaze, Dropbox, a friend’s NAS — the file doesn’t care.
  • Scriptability. Automating encryption in backup pipelines, batch jobs, build systems.
  • Send-to-a-specific-person. Public-key encryption is the cleanest model when the recipient is known and has a key.

When it’s not the right tool

Don’t use GPG when:

  • You want a folder you can just edit files in. That is a Cryptomator use case, not a GPG one. GPG is for discrete encrypt and decrypt operations, not live working folders.
  • You need to share with non-technical people. Getting a non-technical recipient to install GnuPG, generate a keypair, verify fingerprints, and use the command line is usually not feasible. For those situations, see Expiring links and sharing to non-technical people.
  • You want ephemeral, forward-secret messaging. Use Signal.
  • You need to collaborate on live documents. Use a platform with proper access control.

A few gotchas worth knowing

  • GPG’s default cipher has changed over time. Old files (pre-2017-ish) may use CAST5 or Blowfish. New files should be AES-256. Being explicit with --cipher-algo AES256 avoids surprises.
  • --armor produces ASCII output (.asc files) that survives email transport. Without it, GPG produces binary output (.gpg) that is ~33% smaller but shouldn’t be pasted into plain text.
  • Keyring location. On most systems, GPG stores keys in ~/.gnupg/. Back that directory up. If you lose it, you lose every decrypted file ever encrypted with those keys.
  • Subkeys. A mature GPG setup uses a primary key kept offline (for certification) and subkeys on day-to-day devices (for signing and encryption). Complicated; worth reading about once you’re comfortable with the basics.
  • --trust-model always is a shortcut people use to skip fingerprint verification. It is the shortcut that turns GPG into a less-safe version of itself. Don’t use it for anything sensitive.

GPG is not for everyone. For the cases where it fits, it is remarkable how much control it gives you for so little operational cost — and how durably. A file you encrypted with GPG in 2010 is a file you can decrypt in 2030 with no subscription, no vendor, no connection to the internet. That property is worth the command-line unfamiliarity for the documents that warrant it.

Sources

  1. GnuPG — The GNU Privacy Guard
  2. RFC 9580 — OpenPGP
  3. EFF — Surveillance Self-Defense: An Introduction to Public Key Cryptography and PGP
  4. NIST SP 800-175B Rev. 1 — Guideline for Using Cryptographic Standards
  5. GnuPG — The GNU Privacy Handbook