Contents

Encrypted File Containers

I recently came across the need to encrypt some files. I am already running with full disk encryption however wanted something portable that could be transferred between hosts and decrypted as needed. Running mainly Linux, the baked in choice is Linux Unified Key Setup (LUKS).

The following setup will end up looking like this diagram

Creating an encrypted container

Create a file

First step is to create a regular file sized to however big you want the container. This can be done many different ways. The truncate command is nice and easy but a part of coreutils and not guaranteed to be on every system. dd on the other hand is pretty ubiquitous.
In the examples, we are creating a 1G file.
Using truncate
truncate -s 1G container.img
Using dd
dd if=/dev/urandom of=container.img bs=1M count=1024

Attach to a loopback device

Now that we have our file, we need to attach it to a loop device in order to encrypt it. losetup is the go to tool for loopback manipulation. The following command will find the first available loopback device and then use that device to attach our file to.
sudo losetup --show -f ./container.img
Take note of the loopback device assigned (printed out) as we will use it in the next step.

Loopback Device Info
Information on loopback devices and their mappings can always be retrieved using losetup -l

Encrypt

With all of the setup done, we can now encrypt. For as complicated as encryption can be, Linux makes things easy with the cryptsetup command. This one command will let us encrypt / decrypt as well as modify existing encryption schemes on devices. To encrypt our file, we use the following command.

Double Check Loopback Name!
Your loopback device might be named differently dependent on what loopbacks are already in use on your system. Please double check losetup -l before you run this command as it is destructive.
sudo cryptsetup luksFormat /dev/loop0

Opening container

We now have an encrypted file, not much use until we can open it, put a filesystem on it, and store some files. First off, lets open it using the same command we used to encrypt cryptsetup. The following command will open the container allowing it to be read and written to. This command allows you to specify a string that will become a device mapper entry that we can later reference when running actions on the encrypted partition. In this example, we use “secure”.
sudo cryptsetup open --type luks /dev/loop0 secure

Open vs Decrypt
When you run the open command, cryptsetup does not decrypt any of your date. What happens is that your passphrase is used to decrypt the master key. This master key is placed in kernel memory and used by the kernel module dm_crypt. This module sits between the filesystem and the block device transparently decrypting / encrypting as you request and process data.

Write a filesystem

With our file open we can put a filesystem on it. Any filesystem will do however if you intend this to be portable, might be a good idea to choose something that is present on most Linux systems. For sake of example, I will be using ext4.
sudo mkfs.ext4 /dev/mapper/secure

Mount and store some files

Final step! Our encrypted container is open, has a filesystem, and now just needs to be mounted. This is done in the typical fashion using the mount command.
sudo mount /dev/mapper/secure /mnt
A this point, we can add files and write to it at /mnt as if it was a normal part of our file tree.

Closing container

Once done, the device can be unmounted, closed, and detached from the loopback.
sudo umount /mnt
sudo cryptsetup close secure
sudo losetup -d /dev/loop0

Best Practices

Few things to keep in mind to make sure you accidentally loose your data

  • Backup your LUKS Header! - If the LUKS header becomes corrupted, all encrypted data will be lost. Backups can be done with sudo cryptsetup luksHeaderBackup /dev/loop0 --header-backup-file backup.bin
    If you ever change your passphrase, be sure to regenerate your backup and delete the old one as access to it and the old passphrase will give access to your data
  • Take care when updating your passphrase - LUKS allows up to 8 keyslots. Any one of the 8 keys can decrypt the master key which then is used to decrypt the data. If you need to update the passphrase, add it in one of the secondary slots, test that it works, and then remove the old passphrase.