GnuPG - Как отредактировать файл без расшифровки и сначала сохранить на локальный диск? - PullRequest
18 голосов
/ 02 октября 2009

Я использую GNUPG для шифрования моих файлов ascii.

Я научился генерировать ключ, а также как использовать его для шифрования и дешифрования файла.

Я использовал два способа:

gpg -d foo.txt.gpg

и

gpg --output foo.txt --decrypt
foo.txt.gpg

Я понял, что первый метод отобразит расшифрованный файл на экране, например, когда я выполнил команду через SSH.

Что касается второго метода, я обеспокоен, если он оставит след на локальном компьютере - Файл foo.txt.

Самое главное, я не знаю, как редактировать содержимое файла foo на лету. В идеале я хотел бы открыть файл через SSH с помощью nano / pico, набрать мою фразу-пароль для расшифровки, затем отредактировать файл, сохранить его и зашифровать. Мне очень нравится избегать сохранения каких-либо файлов на локальный диск.

Любые комментарии приветствуются.

Заранее спасибо.

Ответы [ 14 ]

5 голосов
/ 02 октября 2009

Один способ использует vim. См. эту страницу и этот связанный вопрос.

Если вам нужна большая гибкость или вы не хотите использовать vim, написание короткой программы для чтения расшифрованного текста, полученного из STDOUT, редактирования по своему вкусу и повторного шифрования не так уж сложно. Например, вы можете использовать этот минимальный код Python (104 строки!), Чтобы предоставить вам простой редактор, а затем добавить функцию чтения и записи потока самостоятельно.

4 голосов
/ 06 сентября 2012

Я написал скрипт для решения этой проблемы (только для 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)
3 голосов
/ 03 октября 2009

Следует иметь в виду, что хранение незашифрованных данных в памяти не гарантирует, что они не попадут на диск. Если рассматриваемая система находится под большой нагрузкой, любые незашифрованные данные могут быть записаны в раздел подкачки. Аналогичным образом, если система переведена в спящий режим, состояние любых приостановленных процессов будет сохранено на диске. Если ваша программа работает во встроенной системе, возможно, что ваша память и «диск» - это одно и то же.

Системный вызов mlock() защитит выделенную память от перезаписи на диск. Однако это требует административных привилегий и ограничивает вас языком низкого уровня, где вы непосредственно отвечаете за управление памятью.

Тем не менее, разумно избегать создания файлов с незашифрованными данными. Просто знайте, что это не дает вам 100% безопасности, если базовая система взломана.

2 голосов
/ 24 мая 2013

Где находится плагин gnupg - именно для этой точки, например

1 голос
/ 06 октября 2014

Вдохновленный ответом Люка, я сам написал скрипт на Python. Надеюсь, кто-нибудь найдет это полезным. Вот основные характеристики:

  • использует временный файл в / dev / shm, используя безопасный метод для генерации временного файла
  • создает файл резервной копии на случай сбоев
  • оба режима шифрования (открытый ключ / симметричный)
  • создание нового файла на лету
  • выберите ваш редактор через переменные окружения

Дополнительную информацию можно найти в самом скрипте. В настоящее время он не будет работать на любой машине, кроме * nix.

Чтобы установить скрипт, просто поместите его в любой каталог на вашем пути и сделайте его исполняемым.

Получи это сейчас!

Внимание: сделайте резервную копию ваших данных! Скрипт поставляется без каких-либо гарантий!

1 голос
/ 02 октября 2009

В качестве альтернативы можно использовать файловую систему tmp в ram, используя tmpfs, тогда, когда вы выключаете ее, она исчезает навсегда.

0 голосов
/ 21 октября 2017

Вот небольшое улучшение в ответе @ Люка. Это делает два небольших улучшения:

  • Позволяет избежать трассировки стека, если файл не был изменен во время сеанса редактирования.

  • Восстанавливает исходный файл gpg, если была предпринята попытка повторного шифрования обратно в исходный файл gpg, что немного безопаснее, чем проверка дат изменения файла редактирования.

#!/usr/bin/python

# Downloaded from /928147/gnupg-kak-otredaktirovat-fail-bez-rasshifrovki-i-snachala-sohranit-na-lokalnyi-disk#928166
# and then slightly improved.

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)


reEncrypted = False
try:
    ## Get password
    passwd = getpass.getpass()

    ## decrypt file
    tmpFile = os.path.join(tmpDir, 'data')
    cmd = "gpg -d --cipher-algo AES256 --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:
        print "Data unchanged; not re-writing encrypted file."
    else:
        ## re-encrypt, write back to original file
    reEncrypted = True
        cmd = "gpg --yes --symmetric --cipher-algo AES256 --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 re-encryption was attempted, restore the backup.
    if reEncrypted:
        print "Error occurred; restoring encrypted file from backup."
        shutil.copy(bakFile, dataFile)
    raise
finally:
    shutil.rmtree(tmpDir)
    os.remove(bakFile)

Я бы опубликовал эти предлагаемые улучшения в качестве комментариев к ответу @ Люка - что мне очень нравится - но у меня не было достаточно очков репутации, чтобы сделать это. (

0 голосов
/ 10 октября 2015

Я потратил бесчисленные часы и на этот квест: просто зашифруйте текстовый файл парольной фразой с простым доступом open + read / write. Я не хотел иметь дело с закрытыми / открытыми ключами или связками ключей, привязанными к логину ОС, бла, бла, бла. Шифрование файлов только с помощью ключевой фразы настолько просто и универсально, что идеально подходит для простого текстового файла с паролями. Нет раздувания и усложнения решения на основе базы данных, такого как KeePass и т. Д. (Которое также требует ввода данных в несколько элементов графического интерфейса пользователя, а не просто ввода паролей в текстовом файле с возможностью поиска). Золотой стандарт на Windows - Steganos LockNote. Как это сделать на Linux? Удивительно, но очень трудно найти, но ...

Я наконец сошлась на рекомендации, которую считаю лучшей: крем. http://cream.sourceforge.net/ Cream - это фасад для vim, который делает его более удобным для пользователя ... полезным для других членов семьи (я - специалист по Linux, работающий с vi [m], но мне нужно что-то более доступное для моя семья).

Просто введите:

"vim -x yourfile.txt"

Он будет сохранен как зашифрованный с парольной фразой.

Вы можете использовать vim или cream на этом этапе:

"vim yourfile.txt" или "cream yourfile.txt".

Любой из них откроет «yourfile.txt» и запросит пароль, а также разрешит редактирование и повторное сохранение в зашифрованном виде. НАКОНЕЦ квест завершен !!!!

0 голосов
/ 18 января 2015

Использование редактора Джо (он же Собственный редактор Джо ) в команде, аналогичной

gpg --decrypt foo.txt.gpg | joe - | gpg --armor --recipient name@example.com --encrypt > bar.txt.gpg

сделает то, что вы ищете.

- в joe - говорит Джо взять свой ввод из стандартного ввода и записать его вывод в стандартный вывод при сохранении файла (нажмите ctrl + k , а затем х для сохранения). Джо сначала покажет грубый вывод из gpg; это можно очистить, нажав ctrl + r , чтобы обновить экран.

Я использую > bar.txt.gpg для указания выходного файла вместо --output bar.txt.gpg, потому что флаг --output заставляет gpg открывать интерактивный диалог, если вы перезаписываете выходной файл, и это сбивает с толку joe.

0 голосов
/ 05 марта 2014

viencrypt от Paul Tarjan - скрипт для редактирования зашифрованных файлов GPG на лету.

...