Editing encrypted files in Emacs
I routinely store note files (normally using org-mode
) in Git repos, which I commit automatically using git-auto-commit-mode.
This works really well, but sometimes I’m working on some notes that I want to be ultra-safe in the event that my Git repo is maliciously accessed. On these occasions, I make use of Emacs’ transparent support for editing GPG-encrypted files. Emacs does a fine job of transparently decrypting files when I open them, and encrypting them when I save them. However, I need to make sure that the encryption keys I use for the files are portable across machines, otherwise I might end up with files I can never open again! 😅
In this post, I briefly describe how I make keys portable, as well as how I use Emacs to edit encrypted files.
Generating, exporting, and importing a GPG key
Before using a key to encrypt your notes, you need to generate a key, and make sure you can use it between machines.
Step 1: generating a new key-pair
First of all, generate a new key with:
gpg --full-generate-key
Once you’ve generated a key, you should be able to see it with:
gpg --list-keys
You should see some output like this:
pub ed25519 2024-01-01 [SC]
3453298457893DFHJKEHFGKJHFGKJSEH34Y78365
uid [ultimate] James Kirk (Self-destruct key) <[email protected]>
sub cv25519 2024-01-01 [E]
Make a note of the key’s ID, which is 3453298457893DFHJKEHFGKJHFGKJSEH34Y78365
in this example.
Step 2: exporting the keys
Now, you can export it as plain-text with:
gpg --armor --export-key 3453298457893DFHJKEHFGKJHFGKJSEH34Y78365 > public.key
gpg --armor --export-secret-key 3453298457893DFHJKEHFGKJHFGKJSEH34Y78365 > private.key
Keep these files safe, and take care transmitting them to your other machines! I store them in a password manager.
Step 3: importing they keys elsewhere
These keys can be imported with:
gpg --import public.key
gpg --import private.key
And, finally, your imported key can be trusted with:
gpg --edit-key 3453298457893DFHJKEHFGKJHFGKJSEH34Y78365 trust quit
At the menu, choose option 5: ultimate trust.
Now you’re all set with an encryption key you can distribute between your machines! 🔒
💡 A note on asymmetric, versus symmetric encryption
GPG supports symmetric encryption with a passphrase, as well as asymmetric encryption (which is what the key set-up above is for). Using symmetric encryption across different machines is easy; all you need is the passphrase, and you can decrypt your files anywhere. For symmetric encryption, you don’t need to create keys, or distribute them across machines.
However, whilst this makes the set-up easier, it is less ergonomic on a day-to-day basis. The passphrase for symmetric encryption is required to encrypt and decrypt the file, and (in my experience) GPG agent prompts for this passphrase regularly (e.g. every write to the file). On the other hand, with asymmetric encryption, the file can be encrypted using the public key (which requires no passphrase), and the GPG agent does a good job of caching the passphrase for the private key.
So, although it’s more effort to set-up asymmetric encryption, I prefer it for everyday encryption of files, because it limits the number of times I need to enter my passphrase.
Configuring Emacs to work well with encrypted files
If you want to automatically encrypt files with a *.gpg
extension when you save them, you might also find these Emacs settings useful.
First, allow passphrases to be entered directly in Emacs from the minibuffer:
(setq epg-pinentry-mode 'loopback)
Next, disable the dialog you’re normally presented with to select an encryption key:
(setq epa-file-select-keys nil)
Setting epa-file-select-keys
to nil
also presupposes that you’ll be using symmetric encryption.
Finally, in order for epa-file-select-keys
to take effect, set epa-file-encrypt-to
as a directory-local variable:
((nil . ((epa-file-encrypt-to . "[email protected]"))))
If, like me, you’re also making use of git-auto-commit-mode
, your .dir-locals.el
might look like this:
((nil . ((eval git-auto-commit-mode 1)
(epa-file-encrypt-to . "[email protected]"))))
Summary
So there you have it! If you want to make use of Emacs’ built-in GPG encryption capabilities to automatically encrypt *.gpg
files when they’re saved, you need to:
- Generate, store, and distribute a GPG key that you can use everywhere you want to encrypt/decrypt your notes.
- Set the
epg-pinentry-mode
andepa-file-select-keys
variables globally. - Set the
epa-file-encrypt-to
on a per-file, or per-directory basis. C-x C-s
and profit!