Encryption Guide for Linux

Encryption transforms readable data into ciphertext that can only be reversed with the correct key. On Linux, encryption protects data at rest -- on disks, USB drives, and individual files -- so that even physical theft or a discarded hard drive does not expose confidential information. Data in transit is covered separately under TLS. This guide focuses on disk encryption with LUKS and dm-crypt, file-level encryption with GPG and eCryptfs, encrypted USB drives, and key management best practices.

Hub: Linux Security Hardening | See also: SSL/TLS Certificates, SSH Hardening

Full-Disk Encryption with LUKS

LUKS (Linux Unified Key Setup) is the standard for disk encryption on Linux. It stores metadata in a header at the beginning of the partition so that multiple passphrases or key files can unlock the same volume. Under the hood, LUKS uses dm-crypt for the actual encryption but adds a structured header that makes key management practical.

Creating a LUKS Volume

# Identify the target device (DANGER: this destroys all data on the device)
lsblk

# Format the partition with LUKS2 (you will be prompted for a passphrase)
sudo cryptsetup luksFormat /dev/sdb1

# Optionally specify the cipher explicitly
sudo cryptsetup luksFormat --cipher aes-xts-plain64 --key-size 512 \
  --hash sha512 --iter-time 5000 /dev/sdb1

# Open (unlock) the LUKS volume and map it to a device-mapper name
sudo cryptsetup luksOpen /dev/sdb1 secure_data

# The decrypted block device is now at /dev/mapper/secure_data
# Create a filesystem and mount it
sudo mkfs.ext4 /dev/mapper/secure_data
sudo mount /dev/mapper/secure_data /mnt/secure

# When finished, unmount and close
sudo umount /mnt/secure
sudo cryptsetup luksClose secure_data

The --iter-time parameter controls how many milliseconds the key derivation function runs. Higher values make brute-force attacks slower but also make unlocking slightly slower for the legitimate user. The default of 2000 ms is a reasonable balance; increase it for highly sensitive volumes.

Automating LUKS at Boot with /etc/crypttab

For volumes that should be unlocked every time the system boots, add an entry to /etc/crypttab:

# /etc/crypttab
# <name>       <device>         <key file>         <options>
secure_data    /dev/sdb1        none                luks,timeout=30

# If using a key file instead of a passphrase:
secure_data    /dev/sdb1        /root/luks-keyfile  luks

Then add the corresponding mount point to /etc/fstab:

/dev/mapper/secure_data   /mnt/secure   ext4   defaults   0 2

Managing LUKS Key Slots

LUKS supports up to eight key slots. You can add a backup passphrase or a key file without removing the original:

# Add a new passphrase to the next available slot
sudo cryptsetup luksAddKey /dev/sdb1

# Generate and add a key file
sudo dd if=/dev/urandom of=/root/luks-keyfile bs=4096 count=1
sudo chmod 0400 /root/luks-keyfile
sudo cryptsetup luksAddKey /dev/sdb1 /root/luks-keyfile

# View key slot usage
sudo cryptsetup luksDump /dev/sdb1

# Remove a specific key slot by slot number
sudo cryptsetup luksKillSlot /dev/sdb1 1

# Remove a key by providing the passphrase to remove
sudo cryptsetup luksRemoveKey /dev/sdb1

# Back up the LUKS header (critical for recovery)
sudo cryptsetup luksHeaderBackup /dev/sdb1 \
  --header-backup-file /root/sdb1-header.bak

Always store header backups offline in a physically secure location. If the LUKS header is corrupted and you have no backup, the data is permanently and irrecoverably lost. Keep at least two copies of the header backup in different physical locations.

Plain dm-crypt

Plain dm-crypt provides a lower-level interface without the LUKS header. It is occasionally used when you want to avoid any on-disk metadata that reveals the presence of encryption (plausible deniability):

# Open with a passphrase (no LUKS header written)
sudo cryptsetup open --type plain /dev/sdb1 plain_vol

# Create a filesystem on the mapped device
sudo mkfs.ext4 /dev/mapper/plain_vol
sudo mount /dev/mapper/plain_vol /mnt/plain

The trade-off is significant: you cannot have multiple key slots, there is no way to verify whether the correct key was supplied (a wrong key silently produces garbage data), and there is no header to back up. LUKS is recommended for the vast majority of use cases.

File-Level Encryption with GPG

GPG (GNU Privacy Guard) encrypts individual files rather than entire partitions. It supports both symmetric (passphrase-only) and asymmetric (public/private key pair) modes, making it suitable for encrypting archives before transfer, signing documents, and encrypting email.

# Symmetric encryption (passphrase only, AES-256)
gpg --symmetric --cipher-algo AES256 secrets.tar.gz
# Produces secrets.tar.gz.gpg
# Decrypt with:
gpg --decrypt secrets.tar.gz.gpg > secrets.tar.gz

# Asymmetric encryption (requires the recipient's public key)
gpg --import colleague_pubkey.asc
gpg -e -r [email protected] secrets.tar.gz
# The recipient decrypts with their private key:
gpg --decrypt secrets.tar.gz.gpg > secrets.tar.gz

# Encrypt to multiple recipients simultaneously
gpg -e -r [email protected] -r [email protected] secrets.tar.gz

# Sign a file (proves you created it, does not encrypt)
gpg --sign --armor document.txt

# Sign and encrypt in one step
gpg -se -r [email protected] document.txt

GPG Key Management

# Generate a new key pair (interactive, asks for algorithm and expiry)
gpg --full-generate-key

# List public keys in your keyring
gpg --list-keys

# List your secret (private) keys
gpg --list-secret-keys

# Export your public key for sharing
gpg --armor --export [email protected] > my_pubkey.asc

# Export your private key for backup (guard this with your life)
gpg --armor --export-secret-keys [email protected] > my_privkey.asc

# Set an expiry date on your key (prevents stale keys circulating forever)
gpg --edit-key [email protected]
# At the gpg> prompt, type: expire
# Follow the prompts to set a new expiry, then: save

# Revoke a compromised key
gpg --gen-revoke [email protected] > revocation.asc
gpg --import revocation.asc

eCryptfs for Directory Encryption

eCryptfs is a stacked filesystem that encrypts files individually within an existing directory tree. It is useful when you need to encrypt a home directory or a specific folder without reformatting the underlying partition:

# Install eCryptfs utilities
sudo apt install ecryptfs-utils   # Debian/Ubuntu

# Mount a directory with encryption (interactive prompts)
sudo mount -t ecryptfs /srv/secret /srv/secret
# You will be prompted for passphrase, cipher (aes), key size (256), and
# whether to enable filename encryption

# To make this persistent, add to /etc/fstab with appropriate options:
# /srv/secret /srv/secret ecryptfs defaults 0 0

# Encrypt a home directory for a new user
sudo ecryptfs-setup-private --login-pass=userpassword --user=username

Because eCryptfs encrypts per-file, it works well with backup tools that operate on individual files and with cloud sync tools. The drawback is that file metadata (sizes, counts, timestamps) is still visible on the underlying filesystem, which leaks some information.

Encrypted USB Drives

Combining LUKS with a USB drive creates a portable encrypted volume that you can carry between machines:

# Wipe the drive first (optional but recommended)
sudo dd if=/dev/zero of=/dev/sdc1 bs=1M count=10 status=progress

# Partition and format the USB drive with LUKS
sudo cryptsetup luksFormat /dev/sdc1
sudo cryptsetup luksOpen /dev/sdc1 usb_crypt
sudo mkfs.ext4 /dev/mapper/usb_crypt
sudo mount /dev/mapper/usb_crypt /mnt/usb

# Copy files, then cleanly close
sudo umount /mnt/usb
sudo cryptsetup luksClose usb_crypt

Most modern desktop environments (GNOME, KDE) will prompt for the LUKS passphrase automatically when the drive is plugged in. For headless servers, use cryptsetup luksOpen manually or via a script.

Key Management Best Practices

  1. Use strong passphrases -- at least 20 characters with mixed case, digits, and symbols, or a passphrase of five or more random words (Diceware method).
  2. Store key files on separate media -- never on the same disk they unlock. A key file on the encrypted disk itself is useless.
  3. Back up LUKS headers -- without the header the data is irrecoverable. Store backups in multiple secure physical locations.
  4. Rotate keys periodically -- use luksAddKey to add a new passphrase, verify it works, then luksRemoveKey to remove the old one.
  5. Use a hardware token for GPG keys where possible (e.g., YubiKey with GPG agent) so the private key never exists in extractable form on disk.
  6. Shred plaintext copies -- after encryption, securely delete the original with shred -u or wipe.
  7. Document your recovery procedure -- write down which devices use which key slots and where the header backups are stored. Without documentation, key management is key chaos.

Encryption is the foundation of data protection. Even if every other control fails -- the firewall is bypassed, SSH is compromised, root is obtained -- properly encrypted data remains confidential as long as the key is secure.