Transparently editing encrypting files with GnuPG and Vim

For security to work it has to be automatic and transparent: a security tool should work without me having to think about it. That's why gnupg.vim is fantastic, it encrypts/decrypts files that are opened in Vim automatically using GnuPG. Using it is completely transparent, any file with a .gpg extension that I open with Vim is decrypted and then re-encrypted at the end of the editing session. The best part is it's one of those tools that works so well you forget about it [1]. If you need to to keep password files, encrypted notes or to share files within a group it's worth checking out!

I care about security more than most, but like everyone else my main goal is to get something done. It's easy for the cognitive load that complexity creates to become too much. Convenience wins and over time good practise and discipline drop away. Security researchers are focusing on making security automatic and easy:

"Product developers have come to recognise that we humans are busy, distracted and frequently irrational when using their products; therefore security is being integrated into product design"

Cognitive Hack: The New Battleground in Cybersecurity ... the Human Mind, James Bone p147

gnupg.vim integrates encryption [2] into Vim and my editing process. I don't have to be disciplined or remember any commands. It detects any file with a .gpg, .pgp or .asc suffix and automatically calls gpg to decrypt it. It does require you to have a GnuPG key-pair and to be running a GPG password agent, which are both complex - but when they're up and running it's all seamless!

Install

I'm going to assume that you already have a GnuPG keypair, if not there are lots of guides. You'll also need to have a GPG agent, I use Keychain which is the easiest way if you have to look after SSH and GPG keys.

Install gnupg.vim in the usual way that you handle Vim plugins. I'm using Neobundle, so for me it is:

NeoBundleLoad 'jamessan/vim-gnupg'

In .vimrc add the following:

" Armor files
let g:GPGPreferArmor=1
" Set the default option
let g:GPGDefaultRecipients=["la@la.com"]

The first option sets GPG to armor files for transmission over a text only medium, in other words you can send any files it creates over email fine. The second option is the default public key that you want any file to be encrypted to: this will be your own public key. Note that you can use GPGDefaultRecipients to specify a set of keys separated by commas.

This is not required, but I have some additional configuration in my .vimrc:

augroup GPG
    autocmd!
    autocmd FileType gpg setlocal updatetime=12000
    autocmd CursorHold *.\(gpg\|asc\|pgp\) quit
augroup END

These options set that if nothing happens in an encrypted file for 12 seconds Vim will quit. This stops me accidentally leaving a secure file unencrypted when I leave my desk [3]. The first line clears the autocmd group and for the GPG file type we set updatetime to be 12 seconds. The second option says that when the CursorHold time elapses (12 seconds) Vim will quit. Note that it won't quit if you've made a change and haven't saved the buffer to file or if you're still in insert mode.

The plugin can get confused if it cannot interact with gpg-agent correctly. In .bashrc I have:

GPG_TTY=`tty`
export GPG_TTY

Finally, at the bottom of any file that I want to edit I add the following modeline:

" vim: ft=gpg fdm=marker foldcolumn=2

This specifies that the filetype is gpg, we need this to make the quit after 12 seconds thing work.

Common Usage

Any file ending in .gpg, pgp or asc is automatically recognised.

  • To create a new file do:

    vim somefile.asc
    

The first time it sees a file with the right extension it pops up a buffer window showing you recipients to encrypt the file for. When you save the file it automatically encrypts it using the public keys that were specified.

  • Edit an existing file

When the encrypted file is edited gpg.vim detects that the file is encrypted and decrypts it using the public key it has access to. At the end of the editing session it will re-encrypt it.

  • Warning about unencrypted files

If a file with one of the extensions is not encrypted then it will give you a warning when you open it in Vim.

  • Manual tests

To test it we can also automatically encrypt a file using a public key, something like this:

# Put some text in a file
vim test.txt
# Encrypt the file
gpg --recipient <some@email> --armor --output test.asc --encrypt test.txt
# Test that it decrypts it
vim test.asc

Commands

There are also a few commands, though I rarely use them:

Command Explanation
:GPGEditRecipients Opens a scratch buffer where you can change the list keys that the file is encrypted for. Any recipient that's not know is prepended by a !
:GPGViewRecipients See which public keys are used to encrypt the file.
:GPGEditOptions Opens a scratch buffer to change the options for encryption.
:GPGViewOptions Prints the options.

Final Thoughts

I don't feel I've really done this tool the justice it deserves. It saves me a lot of time and helps me to keep files secure that I probably wouldn't if I had to remember all the GnuPG switches. Transparent, automatic security, it's the way to go!

[1]Dustin made me aware of this tool many years ago in his post So Many Passwords....
[2]Technically Vim comes with encryption built-in, but this is public key cryptology and the transparent file detection is the killer feature.
[3]Thanks to pigmonkey for this tip, from Password Management with Vim and GnuPG

Posted in Tech Sunday 14 May 2017
Tagged with ubuntu security linux vim