Using GPG with Vi


Background

Vi provides its own encryption mechanism. To determine if your vim is built with encryption support, run the following command and look for +cryptv in the list of features.

% vim --version
VIM - Vi IMproved 7.0 (2006 May 7, compiled May 9 2007 19:04:07)
Included patches: 1, 3-4, 7-9, 11, 13-17, 19-26, 29-31, 34-44, 47, 50-56, 58-64, 66-73, 75, 77-92, 94-107, 109, 202, 234-235, 237
Compiled by <bugzilla@redhat.com>
Tiny version without GUI. Features included (+) or not (-):
-arabic -autocmd -balloon_eval -browse +builtin_terms -byte_offset -cindent
-clientserver -clipboard -cmdline_compl -cmdline_hist -cmdline_info -comments
+cryptv -cscope -cursorshape -dialog -diff -digraphs -dnd -ebcdic -emacs_tags
-eval -ex_extra -extra_search -farsi -file_in_path -find_in_path -folding
-footer +fork() -gettext -hangul_input +iconv -insert_expand -jumplist -keymap
-langmap -libcall -linebreak -lispindent -listcmds -localmap -menu -mksession
-modify_fname -mouse -mouse_dec -mouse_gpm -mouse_jsbterm -mouse_netterm
-mouse_xterm +multi_byte -multi_lang -mzscheme -netbeans_intg -osfiletype
-path_extra -perl -printer -profile -python -quickfix -reltime -rightleft -ruby
-scrollbind -signs -smartindent -sniff -statusline -sun_workshop -syntax
-tag_binary -tag_old_static -tag_any_white -tcl +terminfo -termresponse
-textobjects -title -toolbar -user_commands -vertsplit -virtualedit -visual
-viminfo -vreplace +wildignore -wildmenu -windows +writebackup -X11 -xfontset
-xim -xsmp -xterm_clipboard -xterm_save
  system vimrc file: "/etc/virc"
   user vimrc file: "$HOME/.vimrc"
    user exrc file: "$HOME/.exrc"
 fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2
Linking: gcc -L/usr/local/lib -o vim -lselinux -ltermcap -lacl

However, there are signification disadvantages to using this encryption mechanism. First, it is nonstandard encryption. This means files encrypted this way can only be decrypted with vi, no other programs will decrypt it. Next, it is cryptographically weaker than GnuPG. Last it does not automatically disable viminfo and swap files. This leaves the possibility of decrypted data on the disk as a consequence. The better alternative for encryption with vi is GnuPG. However if you still wish to use vi's internal encryption, you call it with the "-x" option.


Sign, Encrypt and Sign/Encrypt

To enable, signing and/or encrypting of a document in vi using gnupg, enter the following lines into your ~/.vimrc file.

map ^E :1,$!gpg --armor --encrypt 2>/dev/null^M^L
map ^G :1,$!gpg --armor --encrypt --sign 2>/dev/null^M^L
map ^Y :1,$!gpg --clearsign 2>/dev/null^M^L

The first macro (ctrl-V ctrl-E) encrypts the entire edit buffer (1,$). The second macro (ctrl-V ctrl-G) encrypts and signs the entire edit buffer and the third (ctrl-V ctrl-Y) only signs the buffer. Note, you can change the gpg options as appropriate, read the gpg man page for further information.

One use of these macros can be seen with the use of the mixmaster client. When it creates a message, mixmaster calls the text editor specified by the EDITOR variable. If the variable is set to vi, then the user can send signed and/or encrypted messages through the mixmaster remailer network.


Editing Encrypted Files Transparently with Vi

Vi can edit gpg encrypted files transparently. After adding the below to your ~/.vimrc file, when editing an encrypted file, vi will prompt you for your passphrase and if successful load the decrypted file into your current buffer. When you save the file, it will re-encrypt it for you. Also vi will recognize encrypted file types by their suffixes, .gpg for binary and .asc for ASCII-armored files. There is no need to pass the "-x" option here.

" Transparent editing of GnuPG-encrypted files
" Based on a solution by Wouter Hanegraaff
augroup encrypted
  au!

  " First make sure nothing is written to ~/.viminfo while editing
  " an encrypted file.
  autocmd BufReadPre,FileReadPre *.gpg,*.asc set viminfo=
  " We don't want a swap file, as it writes unencrypted data to disk.
  autocmd BufReadPre,FileReadPre *.gpg,*.asc set noswapfile
  " Switch to binary mode to read the encrypted file.
  autocmd BufReadPre,FileReadPre *.gpg set bin
  autocmd BufReadPre,FileReadPre *.gpg,*.asc let ch_save = &ch|set ch=2
  autocmd BufReadPost,FileReadPost *.gpg,*.asc
    \ '[,']!sh -c 'gpg --decrypt 2> /dev/null'
  " Switch to normal mode for editing
  autocmd BufReadPost,FileReadPost *.gpg set nobin
  autocmd BufReadPost,FileReadPost *.gpg,*.asc let &ch = ch_save|unlet ch_save
  autocmd BufReadPost,FileReadPost *.gpg,*.asc
    \ execute ":doautocmd BufReadPost " . expand("%:r")

  " Convert all text to encrypted text before writing
  autocmd BufWritePre,FileWritePre *.gpg set bin
  autocmd BufWritePre,FileWritePre *.gpg
    \ '[,']!sh -c 'gpg --default-recipient-self -e 2>/dev/null'
  autocmd BufWritePre,FileWritePre *.asc
    \ '[,']!sh -c 'gpg --default-recipient-self -e -a 2>/dev/null'
  " Undo the encryption so we are back in the normal text, directly
  " after the file has been written.
  autocmd BufWritePost,FileWritePost *.gpg,*.asc u
augroup END

The above recipe also ensures vi will not use viminfo or swap file functionality. This means vi, itself will not write decrypted data to disk. However, this doesn't not mean the kernel won't write the decrypted data to the swap partition if memory becomes low. To prevent this from happening you can do one of three things:

I highly recommend the third option encrypting your swap partition. This option provides encryption coverage for all your files regardless of the program using them when they are in swap. This page covers configuring encrypted swap for Linux.