Yi Tang Data Science and Emacs

GPG in Emacs - First Step Towards Data Security

Table of Contents

  1. WHY?
  2. GNU Privacy Guard (GPG)
  3. EPA - Emacs Interface to GPG
  4. Org-Agenda and Dired
  5. Lisp to Close all GPG Files

WHY?

I have growing concerns about data security. It is not that I have something to hide, it’s that I don’t like how my data is being harvested in general by the big corporations for their own benefits, which is mostly trying to sell me stuff that I don’t need or I purchased already. Seeing the advertisements specifically targeting me motivates me to do something.

Setting my personal cloud seems a bit too extreme, and I don’t have the time for it anyway. So I did a little “off-the-grid” experiment in which I exclusively used an offline Debian laptop for data sensitivity work (password management, personal finance, diary etc). It is absolutely secure for sure, but the problem is accessibility: I can only work when I have access to the physical hardware.

It becomes infeasible when I travel, and it gives me some headaches to maintain one more system. Also, the laptop’s screen is only 720p, I can literally see the pixels when I write; it feels criminal to not use the MBP’s Retina display. Lastly, It cannot be off the grid completely; at one point, I have to back it up to the cloud.

So I spent some time researching and learning. I just need a data protection layer so that I don’t have to worry about leaking private data accidentally by myself, or the cloud storage provider getting hacked.

The benefits include not only having peace of mind but also encouraging myself to work on those types of projects with greater convenience.

GNU Privacy Guard (GPG)

is the tool I settled with. It is a 24 years old software that enables encrypting/decrypting files, emails or online communication in general. It is part of the GNU project which weighs a lot to me.

There are two methods in GPG:

  • Symmetric method: The same password is used to both encrypt and decrypt the file, thus the symmetric in its name.
  • Asymmetric method: It requires a public key to encrypt, and a separate private key to decrypt.

There seems no clear winner in which method is better1. I choose the asymmetric method simply for its ease of use. The symmetric method requires typing the passwords twice whenever I save/encrypt the file which seems too much.

The GPG command line interface is simple. Take the below snippet as an example,

 
gpg -r "Bob" -e foo.org
gpg -o foo2.org -d foo.org.gpg

The first line encrypts the foo.org file using the public key identified as “Bob”. It results in a file named foo.org.gpg.

The second line decrypts the foo.org.gpg file to foo2.org which will be identical to foo.gpg.

EPA - Emacs Interface to GPG

Emacs provides a better interface to GPG: Its EPA package enables me to encrypt/decrypt files in place. So I don’t have to keep jumping between the decrypted file (foo.org) and the encrypted file (foo.org.gpg) while working on it.

Below is the simple configuration that works well for me and its explanation.

 
(require 'epa-file)
(epa-file-enable)
(setq epa-file-encrypt-to "foo@bar.com")
(setq epg-pinentry-mode 'loopback)
  • epa-file-enable: is called to add hooks to find-file so that decrypting starts after opening a file in Emacs. It also ensures the encrypting starts when saving a GPG file I believe.

    To stop this behaviour, call (epa-file-disbale) function.

  • epa-file-encrypt-to: to choose the default key for encryption.

    This variable can be file specific, for example, to use the key belonging to foo2@bar.com key, drop the following in the file

    ;; -*- epa-file-encrypt-to: ("foo2@bar.com") -*-
    
  • epg-pinentry-mode: should be set to loopback so that GPG reads the password from Emacs’ minibuffer, otherwise, an external program (pinentry if installed) is used.

Org-Agenda and Dired

That’s more benefits Emacs offers in working with GPG files. Once I have the EPA configured, the org-agenda command works pretty well with encrypted files with no extra effort.

In the simplified example below, I have two GPG files as org-agenda-files. When the org-agenda is called, Emacs first try to decrypt the foo.org.gpg file. It requires me to type the password in a minibuffer.

The password will be cached by the GPG Agent and will be used to decrypt the bar.org.gpg assuming the same key is used for both files. So I only need to type the passphrase once.

 
(setq org-agenda-files '("foo.org.gpg" "bar.org.gpg"))
(org-agenda)

After that, org-agenda works as if these GPG files are normal unencrypted files; I can extract TODO lists, view the clock summary report, search text and check schedules/deadlines etc.

The dired provides functions to encrypt (shortcut “:e”) and decrypt (shortcut “:d”) multiple marked files in a dired buffer. Under the hood, they call the epa-encrypt-file and epa-decrypt-file functions.

Lisp to Close all GPG Files

It seems that once a buffer is decrypted upon opening or encrypted upon saving in Emacs, it stays as decrypted forever. So I need a utility function to close all the GPG buffers in Emacs to avoid leakage.

 
(defun yt/gpg--kill-gpg-buffers ()
  "It attempts to close all the file visiting buffers whose filename ends with .gpg.

It will ask for confirmation if the buffer is modified but unsaved."

  (kill-matching-buffers "\\.gpg$" nil t)
  )

Before I share my screens or start working in a coffee shop, I would call this function to ensure I close all buffers with sensitive data.

Footnotes

1 stackexchange: symmetric vs asymmetric method

If you have any questions or comments, please post them below. If you liked this post, you can share it with your followers or follow me on Twitter!
comments powered by Disqus