Search:  
Gentoo Wiki

TIP_Encrypted_GNUCash

This article is part of the Tips & Tricks series.
Terminals / Shells Network X Window System Portage System Filesystems Kernel Other

Encrypted GNUCash

Introduction

I've been using GnuCash since a few months ago, and I was worried about having all the information about my accounts, expenses and incomes stored in clear text files. So I thought it would be a good idea to store the data in a more secure way.

This tip uses GnuPG to encrypt files. The shell script basically does the following:

Note: It's quite easy to adapt this script to work with any other program, not only with GnuCash.

You can make a link from your menu, or on the desktop to start it. You can choose how you want to be asked for the password: zenity (gnome, xfce dialog), kdialog (for kde) or, if you prefer to call the script from the shell, a simple text question.

Software you will need

  1. "app-arch/tar"
  2. "app-arch/gzip"
  3. "app-crypt/gnupg"
  4. optionally, but useful: "gnome-extra/zenity" or "kde-base/kdialog"
  5. Your pair of secret/public GnuPG keys have to be set up.
Warning: Test the script on copies of your data first to make sure it is configured correctly. It won't help you much if you end up with encrypted files you can't open anymore.
Code: gpgarmor.sh
#!/bin/bash
# gpgarmor - based on code by Jose Antonio Martin
# rewritten by Johannes Buchner
# 
# This shell script will wrap around any program and protect the data files
# by encrypting it using tar and gpg.
# You can put a link to this script on your desktop or in the menu.
# 
# Adjust the following options:

# program to call
PROG="gnucash"
# executing directory (where your data file lives)
DIR="/home/user/test"
# File which is parameter for the program (PROG). 
# The encrypted file will be called the $BOOK.tar.gz.asc
BOOK="mybook"
# All files that should be protected (archived and encrypted).
FILES="${BOOK} ${BOOK}.*.xac ${BOOK}.*.log"
# Your gpg key ID. Read man gpg section HOW TO SPECIFY A USER ID
KEY="<buchner.johannes@myhost.com>"
# KEY="0xFA9572BD" # another possible format

# less important: 
# which interface you want to use: zenity (gnome/xfce), kdialog (kde) or simple text
INTERFACE_ERR='zenity --error --text'
INTERFACE_PASS='zenity --entry --hide-text --text '

#INTERFACE_ERR='kdialog --error'
#INTERFACE_PASS='kdialog --password '

#INTERFACE_ERR='echo' # INTERFACE_PASS will be read from shell if this is set

function do_error {
	$INTERFACE_ERR "$@"
	cd - &> /dev/null
	exit 1
}

function run_and_encrypt {
	"$PROG" $BOOK
	tar -czf "$BOOK.tar.gz" $FILES || 
		do_error "tar failed on $BOOK"
	gpg --recipient "$KEY" --armor --encrypt "$BOOK.tar.gz" || 
		do_error "gpg encryption failed on $BOOK"
	rm -f $FILES $BOOK.tar.gz
	cd - &> /dev/null
	exit 0
}

cd "$DIR"

test -f "$BOOK.tar.gz.asc" || \
	if test -f "$BOOK"; then
		# Found not-encrypted file (first-run)
		run_and_encrypt || 
			do_error "book \"$BOOK\" not found"
	fi

rm -f "$BOOK.tar.gz"

# Found encrypted file
if [[ "$INTERFACE_ERR" == 'echo' ]]; then
	gpg --quiet --decrypt --output "$BOOK".tar.gz "$BOOK".tar.gz.asc || 
		do_error "gpg decryption failed"
else
	$INTERFACE_PASS 'GnuPG passphrase for '"$KEY"':' |
		gpg --quiet --decrypt --batch --passphrase-fd 0 \
			--output "$BOOK".tar.gz "$BOOK".tar.gz.asc || 
		do_error "gpg decryption failed"
fi


# untar
tar -zxkf "$BOOK.tar.gz"  &> /dev/null
rm -f $BOOK.tar.gz "$BOOK.tar.gz.asc"

run_and_encrypt


A few notes of caution when using the above script:

(1) rm does not destroy the original file from the disc, it simply removes it from the directory. An intruder with suitable hard-disc analysis software can usually retrieve it. A very well-equipped intruder may even recover it after it has been overwritten, if he is willing to make a substantial investment. Safer to precede this with the shred command which overwrites the file several times (e.g., 25) with pseudo-random data.

(2) It is a little dangerous to use pgp public keys for this process. They may have an expiry date set, or a user unaware of the inner workings of this script may discard a PGP public key, thereby rendering the locked files inaccessible. Some might prefer a symmetric key which is sufficient for this purpose. In this case the password should be confirmed (user prompted twice).

(3) It might be safer to pack the entire gnucash directory into the tar ball since not all files correspond to the $FILES mask. However, executing rm -f * is a bit frightening...

This works for me:

Code: gpgarmor.sh
#!/bin/bash
# gpgarmor - based on code by Jose Antonio Martin
# rewritten by Johannes Buchner
# 
# This shell script will wrap around any program and protect the data files
# by encrypting it using tar and gpg.
# You can put a link to this script on your desktop or in the menu.
# 
# Adjust the following options:

# program to call
PROG="gnucash"
# executing directory (where your data file lives)
DIR="/home/pdb/test"
# File which is parameter for the program (PROG). 
# The encrypted file will be called the $BOOK.tar.gz.asc
BOOK="gnucash"
# All files that should be protected (archived and encrypted).
FILES="${BOOK} ${BOOK}.*.xac ${BOOK}.*.log"

#INTERFACE_ERR='zenity --error --text'
#INTERFACE_PASS='zenity --entry --hide-text --text '

INTERFACE_ERR='kdialog --error'
INTERFACE_PASS='kdialog --password '

#INTERFACE_ERR='echo' # INTERFACE_PASS will be read from shell if this is set

function do_error {
	$INTERFACE_ERR "$@"
	cd - &> /dev/null
	exit 1
}

function run_and_encrypt {
	"$PROG" $BOOK
	tar -czf "$BOOK.tar.gz" $FILES || 
		do_error "tar failed on $BOOK"

	if [[ "$INTERFACE_ERR" == 'echo' ]]; then
		gpg --quiet -ca --output "$BOOK".tar.gz.asc "$BOOK".tar.gz || 
		do_error "gpg encryption failed"
	else 
		PASS1=`$INTERFACE_PASS "Enter passphrase"`
		PASS2=`$INTERFACE_PASS "Repeat passphrase"`
		while [ $PASS1 != $PASS2 ]
		do
			$INTERFACE_ERR 'Error. Passphrases do not match'
			PASS1=`$INTERFACE_PASS "Enter passphrase"`
			PASS2=`$INTERFACE_PASS "Repeat passphrase"`
		done
		gpg --quiet -ca --batch --passphrase $PASS1 \
			--output "$BOOK".tar.gz.asc "$BOOK".tar.gz || 
		do_error "gpg encryption failed"
	fi

	shred $FILES $BOOK.tar.gz  > /dev/null
	rm -f $FILES $BOOK.tar.gz 
	cd - &> /dev/null
	exit 0
}

cd "$DIR"

test -f "$BOOK.tar.gz.asc" || \
	if test -f "$BOOK"; then
		# Found not-encrypted file (first-run)
		run_and_encrypt || 
			do_error "file \"$BOOK\" not found"
	fi

# Found encrypted file
if [[ "$INTERFACE_ERR" == 'echo' ]]; then
	gpg --quiet --decrypt --output "$BOOK".tar.gz "$BOOK".tar.gz.asc || 
		do_error "gpg decryption failed"
else
	$INTERFACE_PASS 'Enter passphrase:' |
		gpg --quiet --decrypt --batch --passphrase-fd 0 \
			--output "$BOOK".tar.gz "$BOOK".tar.gz.asc || 
		do_error "gpg decryption failed"
fi


# untar
tar -zxkf "$BOOK.tar.gz"  &> /dev/null
shred $BOOK.tar.gz "$BOOK.tar.gz.asc"
rm -f $BOOK.tar.gz "$BOOK.tar.gz.asc"

run_and_encrypt

Retrieved from "http://www.gentoo-wiki.info/TIP_Encrypted_GNUCash"

Last modified: Thu, 04 Sep 2008 06:23:00 +0000 Hits: 11,534