Crypt: A script for encrypting and decrypting files and folders using GnuPG
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.
crypt.sh
#!/bin/bash
# Set this to the email address you used to set up your keypair.
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