Linux provides several tools for encrypting files. The right tool depends on your specific situation: whether you need to decrypt on the same machine or send the encrypted file to someone else, whether you want passphrase-based or key-based encryption, and whether you need the simplicity of a modern tool or the ecosystem compatibility of established standards.
This guide covers three tools. OpenSSL: already installed on virtually every Linux system, good for symmetric (passphrase) encryption in scripts and automation, and the same library underlying SSL/TLS certificates. GPG (GNU Privacy Guard): the standard for key-based asymmetric encryption, widely used for secure email and file sharing. age: a modern alternative with better usability and current cryptographic defaults, increasingly adopted for backup encryption and key management.
Choosing the Right Tool
| Use case | Best tool | Why |
| Encrypt a file with a passphrase for yourself (backup, local storage) | OpenSSL or GPG symmetric | Simple, no key management. OpenSSL is already installed; GPG symmetric has better default KDF strength. |
| Encrypt for someone else to decrypt | GPG asymmetric or age | They provide their public key; only their private key can decrypt. No shared password needed. |
| Scripting and automation (no interactive passphrase prompt) | OpenSSL with -pass flag | Passphrase can be read from environment variable or file |
| Modern simple encryption, key files, SSH key compatibility | age | Clean interface, X25519 keys, can encrypt to SSH public keys directly |
| Encrypt with an SSL/X.509 certificate public key | OpenSSL smime or pkeyutl | Uses the same certificate infrastructure as HTTPS; recipient decrypts with their private key |
| Full disk or directory encryption | LUKS (cryptsetup) | Block-level encryption; transparent to applications once mounted |
Method 1: OpenSSL Symmetric Encryption
OpenSSL’s enc command encrypts files using a symmetric cipher and a passphrase. The same passphrase both encrypts and decrypts. This is the fastest option with no key management required.
The critical -pbkdf2 flag
Older OpenSSL guides show commands without the -pbkdf2 flag. Without it, OpenSSL uses the legacy EVP_BytesToKey function to derive the encryption key from the passphrase. EVP_BytesToKey is weak by modern standards: it is fast (making brute-force attacks efficient) and uses MD5 by default. Always use -pbkdf2 with a high iteration count.
| # Encrypt a file with AES-256-CBC and PBKDF2 key derivation:
$ openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -salt \ -in secrets.txt -out secrets.txt.enc # You will be prompted for a passphrase. # -aes-256-cbc: AES with 256-bit key in CBC mode # -pbkdf2: use PBKDF2 for key derivation (NOT the legacy EVP_BytesToKey) # -iter 600000: 600,000 PBKDF2 iterations (OWASP 2024 recommendation for SHA-256) # -salt: add random salt to prevent precomputed attacks
# Decrypt: $ openssl enc -d -aes-256-cbc -pbkdf2 -iter 600000 -in secrets.txt.enc -out secrets.txt
# Encrypt with passphrase from environment variable (for scripting): $ openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -salt \ -in secrets.txt -out secrets.txt.enc -pass env:ENCRYPT_PASS
# Encrypt with passphrase from a file (for scripting): $ openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -salt \ -in secrets.txt -out secrets.txt.enc -pass file:/path/to/passfile
# Encrypt a whole directory (tar first, then encrypt): $ tar czf – /path/to/directory | openssl enc -aes-256-cbc -pbkdf2 -iter 600000 \ -salt -out directory.tar.gz.enc # Decrypt and extract: $ openssl enc -d -aes-256-cbc -pbkdf2 -iter 600000 -in directory.tar.gz.enc | tar xzf – |
The OpenSSL enc -aes-256-cbc command without -pbkdf2 is considered insecure for password-based encryption. Some older tutorials and scripts still use the legacy form. If you see openssl enc -aes-256-cbc without -pbkdf2, the command is using weak key derivation. Always include -pbkdf2 and -iter with a current iteration count (600,000 for SHA-256 based on OWASP 2024 recommendations).
Method 2: GPG Symmetric Encryption (Passphrase-Based)
GPG symmetric encryption uses a passphrase but applies a much stronger key derivation function by default than basic OpenSSL. The S2K (String-to-Key) algorithm in modern GPG versions uses Iterated and Salted S2K with AES-256 and SHA-512 by default.
| # Encrypt a file with a passphrase (GPG symmetric):
$ gpg –symmetric –cipher-algo AES256 secrets.txt # Creates secrets.txt.gpg # Prompts for a passphrase (and confirmation)
# With stronger KDF settings explicitly specified: $ gpg –symmetric –cipher-algo AES256 \ –s2k-digest-algo SHA512 \ –s2k-count 65011712 \ secrets.txt
# Decrypt: $ gpg –output secrets.txt –decrypt secrets.txt.gpg
# Encrypt a directory: $ tar czf – /path/to/directory | gpg –symmetric –cipher-algo AES256 -o directory.tar.gz.gpg # Decrypt and extract: $ gpg –decrypt directory.tar.gz.gpg | tar xzf –
# Sign AND encrypt (proves you created the encrypted file): $ gpg –sign –symmetric –cipher-algo AES256 secrets.txt # Recipient decrypts and signature is automatically verified |
Method 3: GPG Asymmetric Encryption (Key-Based)
GPG asymmetric encryption uses a public key to encrypt and a private key to decrypt. The sender encrypts with the recipient’s public key. Only the holder of the matching private key can decrypt. No shared passphrase is needed.
Generate a GPG key pair (if you don’t have one)
| # Generate a new GPG key pair:
$ gpg –full-generate-key # Select: RSA and RSA (or Ed25519 for modern systems) # Key size: 4096 bits for RSA, or use default for Ed25519 # Validity: your choice (0 = never expires, or set an expiry) # Enter your real name, email, and a passphrase for the key
# List your keys: $ gpg –list-keys
# Export your public key to share with others: $ gpg –export –armor your@email.com > mypublickey.asc # Share mypublickey.asc. It is a public key: safe to share.
# Import someone else’s public key: $ gpg –import theirpublickey.asc |
Encrypt and decrypt with GPG keys
| # Encrypt a file for someone (using their public key):
$ gpg –encrypt –recipient their@email.com secrets.txt # Creates secrets.txt.gpg # Only the holder of their@email.com’s private key can decrypt this.
# Encrypt for multiple recipients: $ gpg –encrypt –recipient alice@example.com –recipient bob@example.com secrets.txt # Either Alice or Bob can decrypt with their own private key.
# Encrypt for yourself (for backup you can decrypt later): $ gpg –encrypt –recipient your@email.com secrets.txt
# Decrypt (GPG automatically uses the matching private key): $ gpg –output secrets.txt –decrypt secrets.txt.gpg # You will be prompted for your private key passphrase.
# Encrypt AND sign (proves sender identity + confidentiality): $ gpg –encrypt –sign –recipient their@email.com secrets.txt |
Method 4: age (Modern Tool with Simpler Interface)
age (pronounced ‘aghe’) is a modern file encryption tool with a deliberately simple design. It uses X25519 for key exchange and ChaCha20-Poly1305 for encryption. Its key advantage over GPG is simplicity: there is no key server, no web of trust, no extensive configuration. It also supports encrypting directly to SSH public keys, which is useful if you already have SSH keys set up.
| # Install age:
# Debian/Ubuntu: apt install age # macOS (Homebrew): brew install age # From releases: github.com/FiloSottile/age/releases
# Generate an age key pair: $ age-keygen -o mykey.txt # Outputs a file with the private key. # The public key is printed to stdout (also inside mykey.txt as a comment). # Public key looks like: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Encrypt for a recipient (using their age public key): $ age -r age1RECIPIENTPUBLICKEY -o secrets.txt.age secrets.txt
# Encrypt for yourself: $ age -r $(grep ‘public key’ mykey.txt | awk ‘{print $NF}’) -o secrets.txt.age secrets.txt
# Encrypt with a passphrase instead of a key: $ age -p -o secrets.txt.age secrets.txt
# Encrypt directly to an SSH public key: $ age -r “$(cat ~/.ssh/id_ed25519.pub)” -o secrets.txt.age secrets.txt
# Decrypt: $ age -d -i mykey.txt -o secrets.txt secrets.txt.age
# Encrypt a directory: $ tar czf – /path/to/directory | age -r PUBLICKEY -o directory.tar.gz.age $ age -d -i mykey.txt directory.tar.gz.age | tar xzf – |
Encrypt Using an SSL/X.509 Certificate (OpenSSL S/MIME)
Because OpenSSL handles both TLS certificates and file encryption, you can encrypt a file using the public key from an X.509 certificate. The recipient decrypts using their private key. This uses the same certificate infrastructure as HTTPS and S/MIME email signing.
This is useful when you already have an X.509 certificate for someone (from their website, their email certificate, or a certificate you issued from a local CA) and want to encrypt data for them without establishing a separate GPG key.
| # Encrypt a file using a recipient’s X.509 certificate:
$ openssl smime -encrypt -aes256 \ -in plaintext.txt \ -out encrypted.smime \ recipient.crt # recipient.crt is the recipient’s X.509 certificate (public key only) # Only the holder of the matching private key can decrypt.
# Decrypt (recipient uses their private key): $ openssl smime -decrypt \ -in encrypted.smime \ -out decrypted.txt \ -recip recipient.crt \ -inkey recipient.key
# Extract the public key from any X.509 certificate and encrypt directly: $ openssl x509 -pubkey -noout -in cert.crt > pubkey.pem # Encrypt a small file or symmetric key with RSA public key: $ openssl pkeyutl -encrypt -pubin -inkey pubkey.pem \ -in symmetric_key.bin -out symmetric_key.enc # Decrypt: $ openssl pkeyutl -decrypt -inkey private.key \ -in symmetric_key.enc -out symmetric_key.bin |
The connection to SSL certificates: S/MIME email encryption uses the same X.509 certificate infrastructure as HTTPS. A certificate issued by a CA for email encryption (with the emailProtection extended key usage) can sign and encrypt emails. The same cryptographic principles that protect your HTTPS connection protect your encrypted files: asymmetric key exchange establishes a session key, and a symmetric cipher (AES-256) does the actual data encryption. OpenSSL is the library implementing both.
After Encrypting: Secure Delete the Original
Encrypting a file creates an encrypted copy. The original plaintext file still exists on disk unless you explicitly delete it. On Linux, standard file deletion (rm) does not overwrite the file contents; it only removes the directory entry. With sufficient effort, the original content may be recoverable from the block device.
| # Overwrite and delete a file (shred):
$ shred -u -z secrets.txt # -u: remove the file after overwriting # -z: add a final overwrite with zeros to hide the shredding
# Shred all files matching a pattern: $ shred -u -z *.txt
# On SSDs and flash storage: shred is less reliable due to wear leveling. # For SSDs, full-disk encryption (LUKS) is more reliable than file-level shred. # The encrypted volume never contains unencrypted data.
# Alternative: wipe (more thorough, supports more wipe patterns): # apt install wipe $ wipe secrets.txt |
Shred is less effective on SSDs, NVMe drives, and any filesystem with journaling or copy-on-write (like Btrfs and some ZFS configurations). The operating system may have written copies of the data in places shred cannot reach. For truly sensitive data on modern storage, full-disk encryption with LUKS is the more reliable approach because the data is never written to the disk in unencrypted form.
Frequently Asked Questions
What is the best way to encrypt files on Linux?
The best method depends on your use case. For encrypting files for yourself with a passphrase (backup, local storage), GPG symmetric encryption with AES-256 provides strong security with good KDF defaults. For encrypting for another person, GPG asymmetric encryption (using their public key) or age are both good choices. For scripting and automation, OpenSSL enc with -pbkdf2 and -iter 600000 is reliable and scriptable. For an entire disk or directory with transparent encryption, LUKS (via cryptsetup) is the standard Linux approach.
Why should I use -pbkdf2 with OpenSSL encryption?
Without -pbkdf2, OpenSSL uses a legacy key derivation function called EVP_BytesToKey that was not designed for password-based encryption. It is very fast, which means an attacker can test billions of password guesses per second. With -pbkdf2 and a high iteration count (600,000 as of OWASP 2024 recommendations), each password guess requires 600,000 hash operations, dramatically slowing brute-force attacks. Always include -pbkdf2 and a high -iter count when encrypting with OpenSSL.
What is age and why might I use it instead of GPG?
age (pronounced ‘aghe’) is a modern file encryption tool that prioritizes simplicity over the extensive features of GPG. It uses X25519 for key exchange and ChaCha20-Poly1305 for encryption. It has no key server, no web of trust, and a simpler command-line interface. It supports encrypting directly to SSH public keys, which means if you already have SSH set up, you can use your existing SSH keys for file encryption without generating a separate GPG key. age is increasingly used for backup encryption and secrets management where GPG’s complexity is unnecessary.
Can I encrypt a file using someone’s SSL certificate?
Yes. OpenSSL’s smime -encrypt command encrypts a file using the public key from an X.509 certificate. The recipient decrypts using their private key. This uses the same certificate infrastructure as HTTPS and S/MIME email. You need the recipient’s certificate file (.crt or .pem); you do not need their private key. Only the holder of the corresponding private key can decrypt the file. This approach works with any X.509 certificate including web server certificates and email certificates.
