Я написал скрипт для решения этой проблемы (только для Linux). Он работает путем расшифровки файла в / dev / shm, чтобы гарантировать, что незашифрованные данные никогда не будут записаны на диск (хотя любая из программ, использующих данные, может быть выгружена на диск; это почти всегда вызывает озабоченность). 1001 *
Это имеет некоторые преимущества по сравнению с другими опубликованными ответами:
- Нужно ввести пароль только один раз
- Работает с любым редактором
Вот код:
#!/usr/bin/python
import os, sys, subprocess, getpass, stat, shutil
editor = 'nano'
dataFile = sys.argv[1]
## make a backup of the encrypted file
bakFile = dataFile+'-gpgedit_backup'
shutil.copy(dataFile, bakFile)
dstat = os.stat(dataFile)
## create temporary directory in tmpfs to work from
tmpDir = '/dev/shm/gpgedit'
n = 0
while True:
try:
os.mkdir(tmpDir+str(n))
break
except OSError as err:
if err.errno != 17: ## file already exists
raise
n += 1
tmpDir += 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)
raise
finally:
shutil.rmtree(tmpDir)
os.remove(bakFile)