A technical blog on Computer Science and Software Development topics by Tomás Pérez.

Transparent symmetric encryption with Vim

Transparent symmetric encryption allows you to edit text files that will be automatically encrypted on writing and decrypted on reading.

There are 2 different methods for enabling this with the Vim editor: the first one relies on the native encryption support included by default and the second one is based on GPG.

Native encryption methods

Vim editor has 3 native modes of encryption

  • pkzip based (deprecated)
  • blowfish based (vim > 7.3)
  • blowfish2 (vim > 7.4.399)

It's highly recommended to use blowfish2 since the 2 first options have well known vulnerabilities [1].

In order to enable blowfish2, you must set the cryptmethod variable cm

set cm=blowfish2

Additional configuration

Even in the native support we need to take into consideration other Vim settings in order to avoid leaving traces of the encrypted files content in the swap, backup or .viminfo files.

set noswapfile
set nobackup
set nowritebackup
set viminfo=

GPG support

In addition to the native methods, Vim can be easily integrated with external encryption engines, the most remarkable being GPG.

The following settings by Wouter Hanegraaff[2] provide transparent editing of GPG encrypted files.

1- Avoid writing to ~/.viminfo while editing

  autocmd BufReadPre,FileReadPre *.gpg set viminfo=
  autocmd BufReadPre,FileReadPre *.gpg set noswapfile noundofile nobackup

2- FileReadPre: switch to binary mode when reading

  autocmd BufReadPre,FileReadPre *.gpg set bin
  autocmd BufReadPre,FileReadPre *.gpg let ch_save = &ch|set ch=2

3- FileReadPost: switch to normal mode for editing

  autocmd BufReadPost,FileReadPost *.gpg set nobin
  autocmd BufReadPost,FileReadPost *.gpg let &ch = ch_save|unlet ch_save
  autocmd BufReadPost,FileReadPost *.gpg execute ":doautocmd BufReadPost " . expand("%:r")

4- FileWritePre: encrypt text before writing

  autocmd BufWritePost,FileWritePost *.gpg u

5- Call to gpg for encrypt/decrypt

The original script does not enable symmetric encryption by default, so we need to change the following lines:

  autocmd BufReadPost,FileReadPost *.gpg '[,']!gpg --decrypt 2> /dev/null
  autocmd BufWritePre,FileWritePre *.gpg '[,']!gpg --default-recipient-self -ae 2>/dev/null

By the customized configuration to force symmetric encryption:

    autocmd BufReadPost,FileReadPost *.gpg '[,']!gpg --decrypt --no-use-agent 2> /dev/null
    autocmd BufWritePre,FileWritePre *.gpg '[,']!gpg --armor --symmetric --no-use-agent --yes --cipher-algo AES256 2>/dev/null

#### Final version of the script


terminal demo