使用gpg2和bash脚本更新加密文件的内容

使用gpg2和bash脚本更新加密文件的内容,bash,encryption,gnupg,Bash,Encryption,Gnupg,假设有一个加密文件file.txt 为了更新其内容,必须先对文件进行解密,然后进行所需的处理,然后再对其进行加密 (1) 在使用gpg2编写bash脚本时,最直接的方法是什么?操作应仅请求用户一次密码解密。它应该在以后的最终加密中使用相同的密码 下面是一个极有可能是极不安全的,但有效的例子,说明了我试图解决的问题: function update-encrypted-file() { read pass_tmp; local pass=$pass_tmp; unset pass

假设有一个加密文件file.txt

为了更新其内容,必须先对文件进行解密,然后进行所需的处理,然后再对其进行加密

(1) 在使用gpg2编写bash脚本时,最直接的方法是什么?操作应仅请求用户一次密码解密。它应该在以后的最终加密中使用相同的密码

下面是一个极有可能是极不安全的,但有效的例子,说明了我试图解决的问题:

function update-encrypted-file() {
   read pass_tmp;
   local pass=$pass_tmp;
   unset pass_tmp;

   local file="file.txt";
   local tmp_result=$(cat $file | gpg2 --batch --passphrase $pass | update);
   echo $tmp_result | gpg2 -c --batch --passphrase $pass > $file;
}
而更新可能是这样的:
alias update=“tr-d X”
(删除所有X)

(2) 究竟是什么使上述示例不安全?我想使用
read
本身是不可能的,但看看原因会很有趣。不在本地设置变量会导致密码在一段短时间内位于全局空间内。那有可能被取出来吗?在这种情况下,我不知道如何使用pinentry tty(请参阅

(3) 除此之外,gpg2文档还对
--passphrase
选项进行了说明:“显然,这在多用户系统上的安全性非常值得怀疑。如果可以避免,请不要使用此选项。”
这只是在终端内手动使用时的情况,因为命令是记录的吗?或者,如果在一个函数内使用,并且密码仅保存在该函数范围内,也会有问题。

我不是直接回答您的个别问题,而是稍微讨论一下密码管理和GnuPG,但对于t第三个问题:机器上运行的所有用户的所有进程的命令行对任何人都可用。要确认,只需作为非特权用户运行一个简单的
ps ax
。永远不要将机密作为参数传递

显然,最安全的选择将是永远不要获得密码短语。如果你没有密码短语,就不能搞乱它。在GnuPG 2.1中,这甚至适用于实际的GnuPG二进制文件(
gpg
/
gpg2
):最关键的密钥操作(涉及处理密码短语)由小型的
gpg代理执行(因此具有较小的攻击面),相当大且复杂的GnuPG二进制文件既不能直接访问密钥也不能直接访问密码短语

这也是我要做的:不要处理密码短语,而是依赖
gpg代理
这样做。它是可用的(而且由于GnuPG 2.1,也是必需的)。如果配置正确(这是默认设置),
gpg agent
将缓存该密码片语一段时间。如果用户配置了其他内容,则他决定不需要缓存的密码片语,您的应用程序也应遵守这一点

一旦需要,
gpg代理将通过配置的方法向用户查询密码短语——如果您正在运行图形用户界面,这可能会弹出一个窗口

如果您弄乱了GnuPG配置(例如,您自己的配置文件,启动您自己的
gpg代理
,…),这当然是您的工作。要启动您自己的
gpg代理实例
以完全控制缓存和其他选项,请根据您的个别用例的要求利用
--options
--homedir
--no-use-standard socket


最后,您将存储内容的中间结果,您可以
echo

local tmp_result=$(cat $file | gpg2 --batch --passphrase $pass | update);
echo $tmp_result | gpg2 -c --batch --passphrase $pass > $file;
不要这样做,原因与讨论的密码短语相同!相反,直接将结果导入加密过程(此处不需要
cat
):

<$file gpg2--batch--passphrase$pass | update | gpg2-c--batch--passphrase$pass>$file;

你确定最后一个例子会起作用吗?我最终得到的是一个空文件,而不是一个更新的文件。这不是因为将stdin和stdout放在同一个文件中的问题吗?例如:文件确实没有考虑到这一点。但是最好先写入一个临时文件,然后再向后移动,而不是将内容存储在一个变量中。你会遇到各种各样的(尺寸)限制,最好不要存储未加密的版本。为了将来参考,
echo$unquotedVar
是一种shell反模式,当
\r\n
或许多Ctrl字符在该值中时,肯定会造成麻烦。通常,dbl会引用所有变量!同意此处不需要它们,除了
“$file”,“$pass”
。祝大家好运。
< $file gpg2 --batch --passphrase $pass | update | gpg2 -c --batch --passphrase $pass > $file;