.

Crypt: A script for encrypting and decrypting files and folders using GnuPG
2008-07-12 07:08 -0400

I recently finished reading Crypto by Steven Levy, and was inspired to set up a public/private key pair for the purposes of encrypting some files on my computer. Having a key pair also allows me to digitally sign emails as well as receive encrypted messages.

I am using GnuPG to handle encryption,decryption, key management, etc. In addition to encrypting single files, I wanted to be able to encrypt whole folders. After researching this, I decided the simplest way to do this would be to tar up the folder and encrypt that. This, however, makes encryption and decryption a two step process. So, I wrote a simple script to handle these steps.

The script attempts to act intelligently based on its arguments. When it encounters directories, it tars then encrypts them. When it encounters an encrypted file, it decrypts it and untars it if necessary. Plain files are simply encrypted. To use the script you must install GnuPG and set up a public/private key pair. I will not cover those steps; there are plenty of resources out there that do (see GnuPG HowTos ). The script is simply called with the files or folders to encrypt or decrypt as arguments. Encrypted files and folders are replaced with files of the same name with a .gpg extension.

#!/bin/bash

# Set this!
recipient=

usage() {
    echo "Usage: $(basename $0) <file | dir>" >&2
} 

error() {
    printf "Error calling \`%s\', exiting...\n" $1 >&2
    exit 1
}

# Check usage.
if [[ $# < 1 ]]; then
    usage
    exit 1
fi

# Process arguments.
until [ -z "$1" ]; do

    # Tar then encrypt directories.
    if [ -d "$1" ]; then
        dir="${1%%/}"
        tar czf "${dir}.tar.gz" "${dir}" || error tar
        gpg --output "${dir}.gpg" --encrypt -r "$recipient" "${dir}.tar.gz" || 
error gpg
        rm -f "${dir}.tar.gz" && \
        rm -rf "$dir"

    # Unencrypt *.gpg files; untar them if necessary.
    elif [[ "$1" == *.gpg ]]; then
        result="${1%.gpg}"
        gpg --output "$result" --decrypt "$1" || error gpg
        if tar -tf "$result" &>/dev/null; then
            mv "$result" "${result}.tar.gz"
            tar -xzf "${result}.tar.gz" || error tar
            rm -f "${result}.tar.gz"
        fi
        rm -f "$1"

    # Must be a plain file, so encrypt it.
    elif [ -f "$1" ]; then
        gpg --output "${1}.gpg" --encrypt -r "$recipient" "$1" || error gpg
        rm -rf "$1"

    # Should never get here.
    else
        echo "Error, I don't know how to handle $1."
        exit 1
    fi

    shift
done