Подтвердить что ты не робот

GnuPG - Как отредактировать файл без дешифрования и сохранения на локальном диске?

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

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

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

gpg -d foo.txt.gpg

и

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

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

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

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

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

Спасибо заранее.

4b9b3361

Ответ 1

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

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

Ответ 2

Я написал python script для решения этой проблемы (только для Linux). Он работает, дешифруя файл в /dev/shm, чтобы гарантировать, что незашифрованные данные никогда не записываются на диск (хотя возможно, что любая из программ, использующих данные, должна быть заменена на диск, это почти всегда вызывает беспокойство).

Это дает некоторые преимущества по сравнению с другими опубликованными ответами:

  • Вам нужно только раз вводить пароль
  • Работает с любым редактором

Вот код:

#!/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

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

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

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

Ответ 4

Где gnupg plugin - именно для этого пункта, например

Ответ 5

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

Ответ 6

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

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

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

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

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

Предупреждение: резервное копирование данных! script поставляется без каких-либо гарантий!

Ответ 7

Если ваш редактор может читать входные данные из канала и сохранять в трубе, вы можете фактически использовать версию gpg, которая расшифровывает на stdout и шифрует из stdin. К сожалению, для nano чтение из трубы только запланировано на 2.4. Например. для gvim вы можете связывать дешифрование и шифрование (через каналы) с ключом.

Ответ 8

Чтобы открыть файлы gpg, отредактировав их, а затем снова перезагрузите/снова сохраните: KGpg Значок в systray имеет возможность: Редактор... Нажмите на него, затем откройте файл gpg, а затем внизу появится кнопка, чтобы расшифровать его, и у вас есть файл в редакторе, после того как вы внесли какие-либо изменения, просто нажмите "Шифровать", а затем сохраните его.

Ответ 9

Только сегодня я узнал о способе делать все это в vim!

вот ссылка: полное руководство по настройке vim для файлов gpg

работает как шарм, только в этом учебнике ссылка на плагин - это URL-адрес страницы, поэтому не нужно ее запускать, а перейдите на страницу и выберите ту, которую вы хотите загрузить.

Ответ 10

Я ненавижу vi, поэтому мне пришлось приклеить клей. Это то, что я придумал. Недостатком является то, что вы должны вводить пароль снова при шифровании.

alias file_ed="gpg file.txt.gpg; nano file.txt; gpg -c --force-mdc -o file.txt.gpg_temp file.txt; mv file.txt.gpg_temp file.txt.gpg; rm file.txt"

Это не очень безопасно с точки зрения файловой системы, но я боюсь других пользователей и себя, а не root.

Ответ 11

viencrypt Пол Тарьян - это script для редактирования зашифрованных файлов GPG на лету.

Ответ 12

Используя редактор joe (aka Joe Own Editor) в команде, подобной

gpg --decrypt foo.txt.gpg | joe - | gpg --armor --recipient [email protected] --encrypt > bar.txt.gpg

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

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

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

Ответ 13

Я тоже потратил немало часов на этот квест: просто зашифруйте текстовый файл парольной фразой с простым открытием + доступом для чтения/записи. Я не хотел иметь дело с закрытыми/открытыми ключами и ключами, связанными с логином ОС, бла, бла, бла. Файловое шифрование с кодовой фразой является настолько простым и универсальным и идеально подходит для простого текстового файла для хранения паролей. Отсутствие раздувания или усложнение решения, управляемого базой данных, такого как KeePass и т.д. (Что также требует ввода данных в несколько элементов GUI, а не просто ввода ваших паролей в текстовом файле с возможностью поиска). Золотым стандартом для 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" и предложит парольную фразу и будет прозрачно разрешать изменения и повторно сохранять в зашифрованном виде. НАКОНЕЦ квест завершен!!!!

Ответ 14

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

  • Он избегает трассировки стека, если файл не изменен во время сеанса редактирования.

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

#!/usr/bin/python

# Downloaded from https://stackoverflow.com/info/1510105/gnupg-how-to-edit-the-file-without-decrypt-and-save-to-local-disk-first/12289967#12289967
# 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)

Я бы разместил эти предлагаемые улучшения в качестве комментариев к ответу @Luke, который мне очень нравится, но не имел достаточных точек репутации для этого.: (