Encrypting Archives¶
Always compress first, then encrypt. Encrypted output looks random and won't compress, so compressing afterwards just burns CPU.
Choosing a method¶
| Method | Use when | Notes |
|---|---|---|
| age | Encrypting files and backups for yourself or your systems | Modern, simple, authenticated; passphrase or public keys (including SSH keys) |
| GnuPG | You already use a keyring, or need signatures | Ubiquitous; more complex |
7z AES-256 + -mhe=on |
Sending a password-protected archive to a person | Hides filenames; recipients need 7-Zip or a compatible tool |
| zip AES-256 | Recipient only has built-in OS tools | Filenames visible |
OpenSSL enc |
Nothing else is installed | No authentication; easy to misuse |
zip -e (ZipCrypto) |
Never for anything sensitive | Broken |
age¶
# Passphrase
tar cf - secrets/ | zstd -T0 | age -p > secrets.tar.zst.age
age -d secrets.tar.zst.age | zstd -d | tar xf -
# Key pair: no prompt when encrypting, only the private key can decrypt
age-keygen -o key.txt # prints the public key
tar cf - secrets/ | zstd -T0 | age -r age1... > secrets.tar.zst.age
age -d -i key.txt secrets.tar.zst.age | zstd -d | tar xf -
# Multiple recipients, or a recipients file
age -r age1aaa... -r age1bbb... -o file.age file
age -R recipients.txt -o file.age file
# Encrypt to an SSH public key; decrypt with the private key
age -R ~/.ssh/id_ed25519.pub -o file.age file
age -d -i ~/.ssh/id_ed25519 file.age > file
Public-key mode is ideal for unattended backups: the backup host only holds the public key, so a compromised host can't decrypt old backups.
GnuPG¶
# Symmetric (passphrase)
gpg -c --cipher-algo AES256 archive.tar.zst # -> archive.tar.zst.gpg
gpg -d archive.tar.zst.gpg > archive.tar.zst
# Asymmetric
gpg -e -r [email protected] archive.tar.zst
gpg -d archive.tar.zst.gpg > archive.tar.zst
# Streamed, skipping GPG's own compression of already-compressed data
tar cf - dir/ | zstd -T0 | gpg -c --cipher-algo AES256 --compress-algo none -o dir.tar.zst.gpg
gpg -d dir.tar.zst.gpg | zstd -d | tar xf -
OpenSSL¶
openssl enc is available almost everywhere, but it has no authentication (tampering isn't detected) and older usage patterns derive keys weakly. If you use it, specify a modern cipher and -pbkdf2 with a high iteration count:
# Encrypt
openssl enc -aes-256-cbc -salt -pbkdf2 -iter 600000 \
-in archive.tar.gz -out archive.tar.gz.enc
# Decrypt (same cipher, -pbkdf2 and -iter)
openssl enc -d -aes-256-cbc -pbkdf2 -iter 600000 \
-in archive.tar.gz.enc -out archive.tar.gz
# Streamed
tar czf - dir/ | openssl enc -aes-256-cbc -salt -pbkdf2 -iter 600000 -out dir.tar.gz.enc
openssl enc -d -aes-256-cbc -pbkdf2 -iter 600000 -in dir.tar.gz.enc | tar xzf -
Avoid openssl des3. Triple-DES is deprecated and slow, and without -pbkdf2 the key comes from a single round of a weak hash, which makes passwords easy to brute-force.
Archive-native encryption¶
| Format | Cipher | Filenames hidden? | Create with |
|---|---|---|---|
zip -e |
ZipCrypto (broken) | No | zip -e |
| zip AES | AES-256 | No | 7z a -tzip -p -mem=AES256 |
| 7z | AES-256 | With -mhe=on |
7z a -p -mhe=on |
| RAR5 | AES-256 | With -hp |
rar a -hp |
Password hygiene¶
- Prefer prompts (
-pwith no value,age -p) over passwords on the command line, which end up in shell history andpsoutput. - For scripts, use key-based encryption (age recipients, GPG public keys) rather than embedding passphrases.
- Store passphrases and private keys in a password manager or
pass, not next to the backups.