Weekend Project: Make a Portable Encrypted File Safe

581

 

Many Linux distributions offer industrial-strength disk encryption tools, either allowing you to encrypt entire partitions or just users’ (including root’s) home folders, at install-time or after the fact. But what if you just need to encrypt a single file or directory, such as a sensitive folder you can ferry back and forth between different sites? And what if you need to ensure that you can access the folder contents even from a non-Linux computer?

The Landscape: Secrets, Keys, Files, and Folders

Owing to its strong Unix roots, there is no shortage of encryption tools for the modern Linux user. Gnu Privacy Guard (GPG), OpenSSL, and OpenSSH are mainstays for protecting email, HTTP, and SSH, respectively; and there are even high quality GUI tools to make short work of the potentially confusing tasks of managing all of the keys, signatures, and webs-of-trust involved. Likewise, full-disk (or, more specifically, full-partition) encryption is important for co-located servers and laptops, and numerous Linux tools have been built for this task, such as EncFS, CryptoFS, and loop-AES.

The trouble with these solutions is that, being primarily designed for a different use case, using them to encrypt a single file or folder is either not possible, not cross-platform, or requires a separate step, such as maintaining and protecting a public key pair. EncFS, for example, is a FUSE filesystem. So while it is simple to set up on a Linux box (particularly with the Cryptkeeper applet), the resulting encrypted folder is not portable onto non-FUSE-capable operating systems.

That’s not to suggest that any of the solutions above are bad; on the contrary, you can easily use GPG to strongly encrypt a single file with gpg -e -r
This e-mail address is being protected from spambots. You need JavaScript enabled to view it
-o encrypted_output_file.pgp unencrypted_input_file.txt
, where
This e-mail address is being protected from spambots. You need JavaScript enabled to view it
is the email address of someone in your keyring. The command could hardly be simpler, and the encryption is air-tight, but it encrypts the file so that only
This e-mail address is being protected from spambots. You need JavaScript enabled to view it
can decrypt it.

OpenSSL, on the other hand, can encrypt a file without tying it solely to a single encryption key. Just type:

 

openssl aes-256-cbc -a -salt -in unencrypted_input_file.txt -out encrypted_output_file.txt.enc.

The openssl binary will prompt you to create a passphrase. The aes-256-cbc parameter specifies the use of 256-bit AES as the cipher, and the -salt parameter adds a salt to the encryption setup for added security.

Anyone with the passphrase can then decrypt the file by running:

openssl aes-256-cbc -d -a -in encrypted_output_file.txt.enc -out newly_decrypted_original_file.txt

This is portable, and OpenSSL is widely available on non-Linux operating systems, but it really only works on a single file.  You could gzip a directory for portability, but there are other ways.

Options for Encrypting Folders on the Fly

Several projects exist to encrypt folders in a more convenient manner, both for portability across operating systems and to leverage the important “on the fly” feature — meaning that once the passphrase for decrypting the folder is entered, the folder’s full contents are immediately available to the user, in a fully transparent manner.

Perhaps the most widely known is TrueCrypt, which is freely available, fully maintained for Linux, Mac OS X, and Windows, and for which source code is available. The biggest obstacle to TrueCrypt is license incompatibility, however — the developers chose to roll their own attempt at an open source / free software license, and most distributions find it incompatible and do not include TrueCrypt packages in their default installs or package management systems. In addition, the makers of TrueCrypt do not maintain a public source code repository and pull old source releases off of their public web site when a new release is made; this also makes maintaining compatibility a serious challenge.

However, if you don’t mind the challenge, you can download the latest TrueCrypt release from the project’s web site.  As of today, the latest version is numbered 6.3a (although this does not represent an “alpha” quality release; another deviation from the usual open source project practices), from November of 2009.  32-bit and 64-bit builds are available for Intel-compatible architectures, in tar archives. The source code is available as a separate download.

TrueCrypt has both a command-line interface and a GUI client. To set up an encrypted directory, the simplest thing to do is walk through the GUI’s “create volume” wizard. You will be creating a TrueCrypt container, which is an encrypted file that TrueCrypt mounts into the filesystem as a regular volume. During setup, you can specify the encryption cipher, hash algorithm, internal filesystem format, and passphrase. You must also pre-choose the total size of the volume — this is one of TrueCrypt’s weak points; it creates the entire volume at a fixed size that cannot be expanded if necessary later. Note also that you cannot encrypt an existing folder with TrueCrypt; you can only create a new volume and copy existing content into it.

For Linux-only folder encryption, a better solution is eCryptfs, which you will probably find packaged as ecryptfs-utils. This is a standard package available on most distributions that works by creating a “stacked” filesystem on top of the existing disk filesystem. There is no eCryptfs binary; rather, when installed, “ecryptfs” becomes a filesystem type option for mount.

To use it, create a new directory, such as mkdir ./filevault. You can then mount that directory on top of itself as type eCryptfs with sudo mount -t ecryptfs ./filevault ./filevault. The first time you mount this directory, the system will prompt you as to whether it should use passphrase, OpenSSL, or other key types for access control, as well as the encryption cipher and block size to use.

Once mounted, ./filevault will behave like any other directory. When you are finished with it, however, you can unmount it with umount ./filevault, and the contents are protected from prying eyes.

If you want, you can specify the passphrase in the mount command on subsequent usage to save a step (perhaps even automating the mount process). Just append it after the -o flag: sudo mount -t ecryptfs -o key=passphrase_passwd=MySecretPassword ./filevault ./filevault. For improved security, you can store the passphrase in a file and use passphrase_passwd_file instead.

True Portability

As mentioned, though, eCryptfs is so far implemented only for Linux. The ciphers it supports are standardized, of course, but the format in which all of these encryption tools write the relevant headers and data to disk is not standardized.

A better long-term idea is to use cryptsetup, a tool developed in concert with LUKS, the Linux Unified Key Setup. LUKS itself is a specification for how encrypted content is stored in the filesystem, which makes it possible to build LUKS-compatible tools for any OS.
Cryptsetup uses the device-mapper infrastructure on Linux, the same subsystem that permits software RAID, logical volume manager (LVM), and other “virtual device” filesystem niceties. The tool is straightforward to use, but unfortunately works on the partition-level only, so you cannot simply create an encrypted directory inside your home folder and move it with ease, as TrueCrypt and eCryptfs permit. Still, if portability is what you need, you can at least encrypt a partition on a removable medium such as a USB key, and be sure that it will be readable on other OSes.

To begin, mount your removable storage device as usual. If it is new, you can devote the entire partition to your LUKS-protected content without further work. If you want to store unencrypted content as well, though, you will need to use fdisk to split the disk into more than one partition. This is probably a good idea in the long run, since it would allow you to use the unencrypted storage to carry some filesystem tools and portable apps, too.

Let’s assume that you make two partitions, /dev/sdd1 for unencrypted storage and /dev/sdd2 for encrypted storage. You then turn /dev/sdd2 into a LUKS-formatted partition with cryptsetup –verbose –verify-passphrase luksFormat /dev/sdd2. Cryptsetup will ask you to choose and verify a passphrase for the partition.

Next, run cryptsetup luksOpen /dev/sdd2 sdd2 and enter your passphrase. This command creates a device-mapper block device named /dev/mapper/sdd2 — this is the device you will use whenever you access this protected storage. You then create a filesystem on /dev/mapper/sdd2 just as if it was a regular physical disk, with mkfs or your distribution’s GUI filesystem tools. Use mkfs.vfat -F 16 /dev/mapper/sdd2 to create a FAT filesystem for maximum portability.

Finally, mount the new filesystem with sudo mount /dev/mapper/sdd2 /home/username/usb_secrets. The contents of the directory will be transparently encrypted when they are written to the physical device, /dev/sdd2, but to all applications, /dev/mapper/sdd2 will be perfectly accessible. The setup is only required once, of course. On subsequent accesses, you only need to run the mount command.

The real magic is that because cryptsetup uses LUKS as its on-disk format, the partition’s contents are readable elsewhere. The best Windows solution is FreeOTFE (for “on the fly encryption”). The FreeOTFE project provides binaries for Windows machines and Windows Mobile devices and even includes a “portable apps” package that you can store on the USB key itself. The situation for Mac OS X is not quite as rosy, although the OSXCrypt project is working on it.

Too Many Secrets?

As is often the case with powerful encryption, you have lots of choices, each with ups and downs. If all you need is to encrypt a single file and send it somewhere in a one-time-use manner, it is hard to beat the OpenSSL example’s simplicity. On the other hand, for folders and repeated usage, you have more complex needs to weigh. eCryptfs is the simplest way to encrypt a directory for Linux, but TrueCrypt is completely cross-platform. If you can stand to limit your protected directory to a USB key, however, Cryptsetup with LUKS offers the best overall mix: the format is standardized for portability, and the encryption is truly transparent to the system when in use.

For extra credit, try creating a USB key that contains one partition for LUKS data, one FAT partition with FreeOTFE tools, and one partition with a small bootable Linux distribution on it as the ultimate fallback. But don’t forget to include the encryption packages in the Linux distro, because doing that would leave you right where you started.