April 24, 2008

Protecting directory trees with gpgdir

Author: Ben Martin

gpgdir uses GNU Privacy Guard (GnuPG) to encrypt and decrypt files or a directory tree. You could accomplish the same objective by tarring the filesystem up and then encrypting the tar.gz file with GnuPG, but then you would still have to shred or wipe every file in the original directory tree. With gpgdir the whole tree is encrypted in one command.

The program's sources as well as i386 and x64_64 RPM files are available on the gpgdir download page. Packages are not available from the standard Ubuntu, openSUSE, or Fedora repositories. For this article I installed from source using version 1.8. gpgdir is written in Perl and requires the GnuPG::Interface, Class::MethodMaker, and Term::ReadKey modules. The distribution tarball of gpgdir contains an install.pl file which installs gpgdir along with these modules if they are not already available on your system. If you run install.pl as a non-root user then the modules and gpgdir will be installed into a subdirectory of your home directory. One minor snag is that the install.pl expects the $HOME/bin directory to exist prior to your executing it; if there isn't one, it prints an error message. Although the installation script could just make the bin directory for you, this would probably lead to confusion, because the new bin directory would not be in your $PATH. The below commands install gpgdir as a non-root user.

$ mkdir -p ~/bin
$ echo PATH=~/bin:$PATH >> ~/.bashrc
$ . ~/.bashrc
$ ./install.pl

The first time you attempt to use gpgdir it will setup a configuration file $HOME/.gpgdirrc and inform you that you must edit that file and specify the default key to use for encryption with the use_key directive. Although the comment for this directive mentions that you should specify the keyid for the key, I found that using the email address of the key works fine too.

Once you've specified a default encryption key, the usage of gpgdir is simple. Pass -e to gpgdir encrypt a directory tree and -d to decrypt it again. An example session is shown below:

$ mkdir testdir
$ date > testdir/df1
$ date > testdir/df2
$ gpgdir -e testdir
[+] Executing: gpgdir -e testdir
Using GnuPG key: gpgdirmain@localhost
Enter password (for initial encrypt/decrypt test)

[+] Encrypting directory: /tmp/testdir
[+] Building file list...
[+] Encrypting: /tmp/testdir/df1
[+] Encrypting: /tmp/testdir/df2

[+] Total number of files encrypted: 2

$ gpgdir -d testdir
[+] Executing: gpgdir -d testdir
Using GnuPG key: gpgdirmain@localhost

[+] Decrypting directory: /tmp/testdir
[+] Building file list...
[+] Decrypting: /tmp/testdir/df1.gpg
[+] Decrypting: /tmp/testdir/df2.gpg

[+] Total number of files decrypted: 2

An option that you will probably want to use all the time when encrypting is the -W/--Wipe option, which will cause the wipe command to be run on an unencrypted file after the file has been successfully encrypted. That way, if somebody swipes your hard disk, they cannot recover the old deleted unencrypted file by scanning your disk for deleted files.

You don't have to use the default key for gpgdir. You can use any GnuPG key with the -K/--Key-id command-line option. Also the --agent and --Agent-info command-line options let you specify whether a gpg-agent should be contacted for your passphrase and where to find that agent if you have multiple agents running.

When gpgdir performs a recursive directory traversal to encrypt files, you can specify which files should be encrypted and which should be left alone. Use the --Exclude or --Exclude-from options to exclude files from being encrypted by passing either a regular expression (regex) pattern on the command line or the name of a file containing many line-separated regexes. The other way around, you can use --Include and --Include-from to explicitly specify which files should be encrypted using regexes.

As the above example shows, normally gpgdir will encrypt a file named foo into foo.gpg. You might like to use the --Obfuscate-filename argument to have random filenames chosen for the encrypted files. This option uses a mapping file in each directory to record what the decrypted filenames were. The mapping file itself is also encrypted so that an attacker cannot see any of the original file names.

Things to watch out for

If you use gpgdir on a directory tree that contains files that have already been encrypted with GnuPG, you may get some surprising results. Consider the case where you have files in the directory which you have encrypted with the same key that gpgdir is using to encrypt and decrypt the directory -- for instance, a file called foo.gpg. In this case, gpgdir will skip encrypting the already encrypted files when encrypting the directory tree and inform you that the files are already encrypted. When decrypting the directory tree again, gpgdir will decrypt all the files. So you end up with a file foo instead of the original state where foo was already encrypted and should be still encrypted as foo.gpg.

Things get much worse if you do not have the key used to encrypt the files -- for example, a file called bar.gpg. In this case, gpgdir will not encrypt the files and comment that it is skipping an already encrypted file bar.gpg when you encrypt the directory. When you attempt to decrypt the directory, gpgdir will fail when it attempts to decrypt bar.gpg and stop all processing. An attempt to use gpgdir's --Force option to have it report the failed decryption but still decrypt the other files in the directory tree still fails at bar.gpg. I could still get at the content of the files in the encrypted directory tree directly with gpg, but I could not figure out how to get gpgdir to decrypt the directory tree without removing the offending file bar.gpg before running gpgdir.

The above issues could be solved if you could force gpgdir to always encrypt files, even if they already had a .gpg extension, instead of skipping over those files. If that were the case, then gpgdir would not attempt to decrypt bar.gpg because it would be decrypting bar.gpg.gpg, which was encrypted with your nominated GnuPG key when using gpgdir -e to encrypt the directory tree.

The --Symmetric option to gpgdir uses the --symmetric option to GnuPG to encrypt the files, and should lead to faster encryption and decryption. I tested normal vs. symmetric using a directory containing the 44MB tar.gz of linux-2.6.23. In normal mode encryption took 5.4 seconds, while symmetric mode took 4.7 seconds. To benchmark symmetric for a directory containing many smaller files I created a new subdirectory with 51 copies of the unencrypted tarball of gpgdir-1.8 in it. Encrypting this directory in normal mode took 9.1 seconds, while symmetric mode needed only 6.7 seconds. To decrypt the directory in normal mode took 6 seconds, and symmetric needed only 5 seconds. Given these small differences in speed you might like to avoid using --Symmetric and just stick with the defaults.

Using an existing encryption tool such as GnuPG to perform your encryption and decryption operations lowers the possibility of a major flaw in your encryption implementation. If you already use GPG for email signing or other tasks, then gpgdir can be handy when you would like to quickly encrypt a directory tree and securely wipe away the original non-encrypted files. Remember to use the -W option when encrypting and avoid directory trees that contain already encrypted files until gpgdir has a method of handling that scenario.


  • Security
  • Tools & Utilities
Click Here!