为什么 GPGME / GnuPG 使用 pinentry 进行密码输入?

Why does GPGME / GnuPG use pinentry for password input?

GPGME 使用 passphrase_cb 方法从用户那里获取密码以进行操作,这需要访问私钥。此回调只能为对称加密覆盖,在所有其他情况下使用默认的 pinentry。

所有这些努力似乎很不舒服,特别是因为 GPGME 是一个 API,应该用于编程 C/C++/... 应用程序。在某些情况下,如果可以将密码短语直接传递给 encrypt/sign 函数,可能会更容易(对于想使用 GPGME 的程序员)。我还看到 OpenPGP 的其他实现(更准确地说是 NetPGP)使用回调。

所以我想知道这样做是否有任何特定的安全原因?

从 2.1 开始,GnuPG 在 gpg-agent 中删除了最关键的私钥功能,以减少对最私密的秘密——私钥的攻击面。

这样的回调不仅会将密码短语暴露给您正在编写的应用程序(这可能意味着比 GnuPG 更大的攻击面),而且 GnuPG 也会知道密码短语。

如果您确实需要控制应用程序的密码输入,您有多种选择。

实施 Pinentry

然后信息流将是:您的应用程序通过 GPGME 调用 GnuPG,GnuPG 从 gpg-agent 请求一些私钥操作,这再次要求您的应用程序提供密码。请注意,这仅在您还使用适当的 pinentry 配置启动 gpg-agent 时才有效(您可能必须启动另一个实例,与系统上已经 运行 的实例分开)。

gpg-preset-passphrase

直接传递密码最重要的用例是在无头守护进程中,没有人等待输入密码。 GnuPG 还带来了一个小实用程序 gpg-preset-passphrase(在 Debian 和衍生版上,它安装为 /usr/lib/gnupg2/gpg-preset-passphrase),它也可用于预缓存密码(因此它不会在可配置的时间内被查询)。

Pinentry 环回

在 GnuPG 2.1 中,添加了另一个选项:在 gpg-agent 中,您可以使用 allow-loopback-pinentry 选项允许 pinentry 环回。在 GnuPG/GPGME 中设置为 loopback 的附加参数 pinentry-mode 应该允许您再次使用 passphrase_cb 处理密码短语交互。

但是:请考虑这会同时暴露您的应用程序和 GnuPG 的密码,并且可能被证明是一个(可能很小但存在并且可能不必要的)安全风险。另外,GnuPG 2.1 还没有广泛传播,如果你不控制环境,这可能是一个问题。