GnuPG - How to edit the file without decrypt and save to local disk first? GnuPG - How to edit the file without decrypt and save to local disk first? linux linux

GnuPG - How to edit the file without decrypt and save to local disk first?


One way is using vim. See this page and this related question.

If you need more flexibility or don't want to use vim, writing a short program to read the decrypted text coming from STDOUT, edit to your liking, and then re-encrypt isn't too difficult. For example, you could use this minimal Python code (104 lines!) to give you the bare bones editor, and then add the stream reading and writing functionality yourself.


One thing to bear in mind is that holding unencrypted data in memory is no guarantee that it wont find its way to disk. If the system in question is under heavy load any unencrypted data may be written to the swap partition. Similarly, if the system is put into sleep mode, the state of any suspended processes will be stored to disk. If your program is running on a embedded system, it's conceivable that your memory and "disk" are one and the same.

The mlock() system call will protect allocated memory from getting swapped to disk. However, this requires administrative privileges and limits you to a low-level language where you are directly responsible for memory management.

That said, it is prudent to avoid creating files with unencrypted data. Just know that this doesn't offer you 100% safety if the underlying system is compromised.


I wrote a python script to solve this (for Linux only). It works by decrypting the file into /dev/shm to ensure that the unencrypted data is never written to disk (although it is possible for any of the programs using the data to be swapped to disk; this is almost always a concern).

This has some benefits over some of the other posted answers:

  • Only need to type the password once
  • Works with any editor

Here is the code:

#!/usr/bin/pythonimport os, sys, subprocess, getpass, stat, shutileditor = 'nano'dataFile = sys.argv[1]## make a backup of the encrypted filebakFile = dataFile+'-gpgedit_backup'shutil.copy(dataFile, bakFile)dstat = os.stat(dataFile)##  create temporary directory in tmpfs to work fromtmpDir = '/dev/shm/gpgedit'n = 0while True:    try:        os.mkdir(tmpDir+str(n))        break    except OSError as err:        if err.errno != 17:  ## file already exists            raise    n += 1tmpDir += str(n)os.chmod(tmpDir, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)try:    ## Get password    passwd = getpass.getpass()    ## decrypt file    tmpFile = os.path.join(tmpDir, 'data')    cmd = "gpg -d --passphrase-fd 0 --output %s %s" % (tmpFile, dataFile)    proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE)    proc.stdin.write(passwd)    proc.stdin.close()    if proc.wait() != 0:        raise Exception("Error decrypting file.")    ## record stats of tmp file    stat = os.stat(tmpFile)    ## invoke editor    os.system('%s %s' % (editor, tmpFile))    ## see whether data has changed    stat2 = os.stat(tmpFile)    if stat.st_mtime == stat2.st_mtime and stat.st_size == stat2.st_size:        raise Exception("Data unchanged; not writing encrypted file.")    ## re-encrypt, write back to original file    cmd = "gpg --yes --symmetric --passphrase-fd 0 --output %s %s" % (dataFile, tmpFile)    proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE)    proc.stdin.write(passwd)    proc.stdin.close()    if proc.wait() != 0:        raise Exception("Error encrypting file.")except:    ## If there was an error AND the data file was modified, restore the backup.    dstat2 = os.stat(dataFile)    if dstat.st_mtime != dstat2.st_mtime or dstat.st_size != dstat2.st_size:        print "Error occurred, restored encrypted file from backup."        shutil.copy(bakFile, dataFile)    raisefinally:    shutil.rmtree(tmpDir)    os.remove(bakFile)