Encrypted hledger with Emacs and GnuPG
A reasonably seamless way to work with encrypted ledger files
2016-07-18
Last month, I went all-in with organizing my life in plain text. I started logging work and study notes in org-mode, and adopted hledger for keeping track of finances.
Both personal notes and financial documents warrant extra security measures. Emacs’ EasyPG integrates seamlessly with my day-to-day emacsing, so I decided to leverage the fact. Below are some short notes on how to get things working with the least amount of hassle.
This blog entry assumes the reader has GnuPG set up on their machine.
Encrypting your text files
EasyPG has a neat way of letting you specify whose public key you’d like to encrypt a given file with. You can set elisp variables in a ‘special’ comment on the first line of the file:
;; -*- epa-file-encrypt-to: ("your.publickey@email.com"); -*-
When emacs reads this file from disk, it will set the buffer-local variable
epa-file-encrypt-to
to your specified email address. This means that, upon
saving, EasyPG will use that public key to encrypt the file.
However, until you actually save the file to disk, and then re-read it, EasyPG will ask you to specify whose key you’d like to encrpyt the file with… Didn’t we just do that via the ‘magic comment’!?
There is a way around this behavior. We’ll force Emacs to interpret the magic
comment by switching to normal-mode
and back.
(defun refresh-buffer ()
"Reload file-local variables"
(interactive)
(let ((v major-mode))
(normal-mode)
(funcall v)))
(global-set-key (kbd "<f5>") 'refresh-buffer)
Now we need to just hit <F5>
once after writing the magic comment. After
that, the file will get auto-encrypted whenever we save with C-x C-s
.
If you have a whole directory of files you’d like to encrypt (like a personal
diary), it’s best to leverage emacs’ ‘directory
variables’ feature. Just
pop a file named .dir-locals.el
in the directory, and inside it, put:
(
(nil . ((epa-file-encrypt-to . ("your.publickey@email.com"))))
)
This will tell EasyPG to encrypt all files you save in this directory with
“your.publickey@email.com”. (The nil
in the car of the first pair stands for
“any major mode”).
Decrypting your text files
This is easiest if you save all your encrypted files as XYZ.gpg
, or
XYZ.gpg.asc
, and then set the following variable:
(setq epa-file-name-regexp "\\.\\(gpg\\|\\asc\\)\\(~\\|\\.~[0-9]+~\\)?\\'")
(epa-file-name-regexp-update)
Upon opening an encrypted file, Emacs (or your window manager) will pop up a modal window asking for your private key passphrase. This only has to be done once in a while, as the passphrase is cached in memory by gpg-agent for some time.
And now, the legder
This is a sample journal file from hledger’s documentation:
; A sample journal file. This is a comment.
2008/01/01 income
assets:bank:checking $1
income:salary $-1
2008/06/01 gift
assets:bank:checking $1
income:gifts $-1
As noted above, we’ll just need to furnish it with EasyPG’s magic variable:
; -*- epa-file-encrypt-to: ("your.publickey@email.com"); -*-
; A sample journal file. This is a comment.
2008/01/01 income
assets:bank:checking $1
income:salary $-1
Then, hit <F5>
, and then save the file as ~/hledger.journal.gpg.asc
. Close
it, and then verify that it’s encrypted via:
$ cat ~/hledger.journal.gpg.asc
-----BEGIN PGP MESSAGE-----
Version: GnuPG v2
hBENO538+KYKbPGzAQf9HlZ7eFwE/V/kCwCRCzA2B1Zvut3MJONtIZ8O0bcAyRLS
xfZt9wlg4v5yZtGji6SH73yzlxdz2VZRjkTb7neVIUz/ySJlrzoS+R1SPEBvBHy+
W5j/+bitbx/gqWMwCC3cn2geSY86mnKmAFdtbFeD56Zyb7sgv0KAghrKUhDUU+lc
Lfl920jsryYu+VjDohJDJyuLGv9j4o62i47D4tQIwSGhFYZArLmqs6et/wKKZWIr
(...)
Now, we’ll tell hledger to always use this file for generating reports. I keep
a separate script named hl
, containing the following:
#!/bin/sh
gpg2 --decrypt $HOME/hledger.journal.gpg.asc 2>/dev/null | hledger -f- "$@"
You can now use hl reg expenses
to feel bad about your wastefulness.
Happy organizing!