18

我正在使用 GNUPG 加密我的 ascii 文件。

我学会了生成密钥,以及如何使用它来加密和解密文件。

我使用了两种方法:

gpg -d foo.txt.gpg

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

我意识到第一种方法会在屏幕上显示解密的文件,例如当我通过 SSH 执行命令时。

关于第二种方法,我担心它是否会在本地 pc 上留下痕迹 - foo.txt 文件。

最重要的是,我不知道如何即时编辑 foo 文件的内容。理想情况下,我想通过 SSH 使用 nano/pico 打开文件,输入我的密码来解密,然后编辑文件,保存并加密它。我非常喜欢避免将任何文件保存到本地磁盘。

欢迎任何意见。

先感谢您。

4

15 回答 15

5

一种方法是使用vim. 请参阅此页面和此相关问题。

如果您需要更大的灵活性或不想使用vim,编写一个小程序来读取来自 STDOUT 的解密文本,根据自己的喜好进行编辑,然后重新加密并不太难。例如,您可以使用这个最小的 Python 代码(104 行!)为您提供最基本的编辑器,然后自己添加流读取和写入功能。

于 2009-10-02T15:31:00.277 回答
4

我写了一个 python 脚本来解决这个问题(仅适用于 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)
于 2012-09-05T21:19:05.603 回答
4

要记住的一件事是,在内存中保存未加密的数据并不能保证它不会找到进入磁盘的方式。如果有问题的系统负载过重,任何未加密的数据都可能被写入交换分区。同样,如果系统进入睡眠模式,任何挂起的进程的状态都将存储到磁盘中。如果你的程序在嵌入式系统上运行,可以想象你的内存和“磁盘”是一体的。

系统调用将mlock()保护分配的内存不被交换到磁盘。但是,这需要管理权限,并将您限制为直接负责内存管理的低级语言。

也就是说,避免使用未加密数据创建文件是谨慎的做法。只要知道如果底层系统受到损害,这不会为您提供 100% 的安全性。

于 2009-10-03T06:37:15.997 回答
2

gnupg 插件在哪里- 例如,正是针对这一点

于 2013-05-24T05:32:57.813 回答
1

另一种方法是使用 tmpfs 在 ram中拥有一个tmp 文件系统,然后当你关闭它时它就永远消失了。

于 2009-10-02T15:31:58.013 回答
1

受卢克回答的启发,我自己编写了一个 Python 脚本。希望有人会发现这很有用。以下是核心功能:

  • 使用 /dev/shm 下的临时文件,使用安全方法生成临时文件
  • 在失败的情况下创建备份文件
  • 两种加密模式(公钥/对称)
  • 即时创建新文件
  • 通过环境变量选择你的编辑器

更多信息可以在脚本本身中找到。它目前不适用于任何非 *nix 机器。

要安装脚本,只需将其放在路径上的任何目录中并使其可执行。

立即获取!

警告:备份您的数据!该脚本没有任何保证!

于 2014-10-06T12:39:40.010 回答
0

在类似于以下的命令中使用编辑器 joe(又名Joe's Own Editor )

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

会做你正在寻找的。

-in告诉 joe在joe -保存文件时从 stdin 获取其输入并将其输出写入 stdout(按ctrl + k然后x保存)。Joe 最初会显示来自 gpg 的一些粗略的输出;这可以通过按ctrl + r刷新屏幕来清除。

我使用> bar.txt.gpg指定输出文件而不是--output bar.txt.gpg因为--output如果您覆盖输出文件,该标志会导致 gpg 打开交互式对话,这让 joe 感到困惑。

于 2015-01-18T04:15:22.243 回答
0

就在今天,我发现了一种在 vim 中完成所有这些操作的方法!

这是链接:关于为 gpg 文件设置 vim 的完整方法

就像一个魅力,就在那个教程中,插件的链接是一个页面的 url,所以不要 wget 它,而是转到页面并选择你要下载的那个。

于 2010-10-14T16:11:36.777 回答
0

Paul Tarjan 的viencrypt是一个用于即时编辑 GPG 加密文件的脚本。

于 2014-03-04T23:59:39.723 回答
0

我讨厌 vi,所以我不得不在 nano 周围补一些胶水。这就是我想出的。缺点是加密时必须再次输入密码。

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。

于 2010-10-20T15:29:09.397 回答
0

如果您的编辑器可以从管道读取输入并保存到管道,那么您实际上可以使用解密到标准输出并从标准输入加密的 gpg 版本。不幸的是,对于 nano,从管道读取仅计划用于 2.4。例如对于 gvim,您可以将解密和加密(通过管道)绑定到 key

于 2009-10-02T15:28:21.750 回答
0

要打开 gpg 文件,编辑它们,然后再次加密/保存,请使用:系统托盘中的 kgpg 图标有选项:编辑器... 按下它,然后打开 gpg 文件,然后在底部有一个解密它的按钮,瞧你将您的文件放在编辑器中,在您进行任何更改后,只需按 Encrypt 然后保存它。

于 2010-09-06T09:14:16.310 回答
0

我编写了一个 shell 脚本来编辑用 gpg 加密的文件。调用它./editgpg.sh path/to/.secrets.gpg,用 vim 编辑,然后用 ':q!' 关闭。Vim 标志 '-n' 只在内存中打开文件。没有临时文件。

#!/usr/bin/env bash


# decrypt CRYPT_FILE, pipe to vim, and encrypt againg whent type ':q!'
edit_crypt_file() {
        echo "Enter your gpg encrypted file passphrase,
edit it with vim, then close the editor with ':q!'."

        # first argument is a file encrypted with gpg
        CRYPT_FILE=$1
        # get password user input
        local pass
        read -sp "Password:" pass

        gpg_flags='--batch --yes'
        vim_flags='- -n -u NONE --not-a-term'

        # vim command to run before exit with ':q!'
        vim_autocmd=":autocmd VimLeave * :%! tee | gpg $gpg_flags --passphrase $pass -o $CRYPT_FILE -c"

        gpg $gpg_flags --passphrase $pass -d $CRYPT_FILE | vim $vim_flags -c "$vim_autocmd"

        # restart agent in order to lose kept password
        gpgconf --kill gpg-agent
        unset pass
}

edit_crypt_file $1

于 2020-08-31T16:46:14.013 回答
0

这是@Luke's answer的轻微改进。它做了两个小的改进:

  • 如果文件在编辑会话期间未修改,它会避免堆栈跟踪。

  • 如果尝试重新加密回原始 gpg 文件,它会恢复原始 gpg 文件,这比检查编辑文件的修改日期安全一点。

#!/usr/bin/python

# Downloaded from https://stackoverflow.com/questions/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 答案的评论发布——我非常喜欢——但没有足够的声誉点来这样做。:(

于 2017-10-21T02:24:32.510 回答
0

我也在这个任务上花费了无数个小时:只需使用简单的打开+读/写访问权限的密码加密文本文件。我不想处理私钥/公钥,也不想处理绑定到操作系统登录的密钥环,等等,等等。仅使用密码的文件加密是如此简单、通用且非常适合用于保存密码的简单文本文件。像 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”并提示输入密码,并透明地允许编辑和重新保存为加密。终于任务完成了!!!!

于 2015-10-10T03:37:59.283 回答