【问题标题】:Purpose of gpg-agent in gpg2gpg2 中 gpg-agent 的用途
【发布时间】:2018-04-26 16:50:10
【问题描述】:

我一直在使用gpg 进行加密。有人建议我应该改用gpg2。当我去使用gpg2时,我几乎无能为力;它会抱怨需要访问私钥,但我似乎无法让它在没有 gpg-agent 运行的情况下使用私钥。

原来我有意禁用了gpg-agent(通过使用chmod -x /usr/bin/gpg-agent);这导致 gpg2 的功能非常有限,并向 stderr 投诉。

我禁用gpg-agent 的原因是因为一系列事件。

首先,我将 SSH 连接到远程机器,“代理”会打开一个弹出窗口,要求我解锁我的 SSH 密钥。我不喜欢这个,因为:

  • 屏幕上的弹出窗口中断了我的工作流程
  • 我的屏幕上的弹出窗口不太可能被注意到,因此它会显示连接停止而不是查询以解锁加密密钥
  • 当我绝对不​​希望我的密码被缓存时,代理似乎缓存了我的密码(很像sudo 对密码缓存的恼人使用,我可以在其配置中禁用它);我总是想为我的加密密钥输入密码,每次它们被用于任何使用它们的程序时
  • 弹出窗口似乎属于一个单独的进程,而我希望 使用密钥的特定进程 来查询密码(即使它是执行实际查询的库);由于我的大部分活动都使用命令行工具,这意味着 GUI 应用程序并不理想,因为我所做的一切都无法访问 X11
  • 在后台自动启动一个单独的进程消除了“一个命令,一个进程”的概念,特别是如果该后台进程在原始命令退出后仍然存在

原来是 GNOME 的关键代理,如果不卸载 GNOME,我就无法卸载代理。所以我只是通过chmod -x /usr/bin/gnome-keyring* 禁用了它。然后我发现 SSH 会退回到另一个代理,所以我也使用相同的方法禁用了它chmod -x /usr/bin/ssh-agent*

当我开始使用gpg 时,我发现它有一个类似的代理,就是我要询问的那个。出于同样的原因,我立即禁用了它;我希望软件始终向我询问密码以使用私钥。我不希望出于任何原因缓存密码。

所以gpg2似乎需要gpg-agent,我想问一下:

  • 我是否对密码缓存的使用过于偏执?我很想看到或被指出对此的讨论。
  • 是否有最佳实践可以更好地避免意外启用缓存密码?
  • 有没有办法在不运行gpg-agent 的情况下使用gpg2
  • 鉴于代理是守护进程,它们应该能够回答查询,是什么阻止了在本地计算机上运行的其他用户或服务能够访问我缓存或存储的凭据?

【问题讨论】:

  • 只想指出,我非常同意这里的观点。这就是我仍然继续使用和安装gpg 而不是gpg2 的原因。
  • 除了 rouge 进程访问套接字的可能性之外,还有可能安装的工具监视通过 d-bus 的所有内容。 d-bus 用于启用套接字通信。当我安装 Ubuntu 16.04 时,我发现很多信息被自动存储在一个数据库文件中,关于正在使用的应用程序和文件,以及另一个似乎存储关于通过 dbus 进行的信息的数据库文件。当然我把它们都禁用了。

标签: security gnupg passphrase gpg-agent


【解决方案1】:

我是否对密码缓存的使用过于偏执?我很想看到或被指出对此的讨论。

您的担忧当然是 IMO。好消息是有一些方法可以自定义 gpg-agent 行为以满足您的需求。例如,使用基于终端的密码提示(PIN 输入)而不是 GUI 提示,并且缓存密码。

是否有一种最佳做法可以更好地避免意外启用缓存密码?

一种快速的解决方案(可能不是最佳实践)是使用以下选项自定义您的 ~/.gnupg/gpg-agent.conf:

# Expire cached PINs (passphrases) after zero seconds
default-cache-ttl 0
max-cache-ttl 0

# If you use your GPG keys for SSH auth...
default-cache-ttl-ssh 0
max-cache-ttl-ssh 0
enable-ssh-support

# Use TTY-based PIN entry program (I see pinentry, 
# pinentry-curses, pinentry-gnome3, pinentry-tty and 
# pinentry-x11 on my system)
pinentry-program /usr/bin/pinentry-tty

我发现以下有关 GPG 关键最佳实践的指南(更多的是关于密钥管理的一般指南,而不是您所要求的)信息丰富且易于遵循:

有没有办法在不运行 gpg-agent 的情况下使用 gpg2?

据我所知,gpg 2.x 没有。手册页声明如下:

   --use-agent
   --no-use-agent
          This is dummy option. gpg always requires the agent.

我有 gpg 2.1.15。

鉴于代理是能够回答查询的守护进程,是什么阻止了在本地计算机上运行的其他用户或服务能够访问我缓存或存储的凭据?

好问题...默认情况下,gpg-agent 使用套接字,因此从技术上讲,以您的用户身份运行的任何进程理论上都可以劫持您的密钥。不过,不要引用我的话。以下是 gpg-agent 如何工作的概述,希望能帮助您开始寻找真正的答案: https://unix.stackexchange.com/questions/188668/how-does-gpg-agent-work

【讨论】:

  • 我有 Ubuntu 16.04 LTS 提供的 gpg2 作为 2.1.11;我已经设置了除 pinentry 程序之外的所有选项。 gpg-agent 似乎不尊重这些选项。将 pinentry 程序设置为 /usr/bin/pinentry-tty 似乎会调用守护进程终端上的 pinentry 程序(或者如果代理的守护进程没有附加终端,则 fail 无法使用代理)并且它会破坏终端的能力进行交互(甚至输入它要求的 PIN)。整个过程看起来很笨拙,感觉好像设计得不好。
  • ...在写完评论后,pinentry-tty segfaulted 这当然无助于培养人们认为它是一个好程序的感觉
  • 我忘了提一件事,你需要在编辑它的配置文件后重新启动 gpg-agent。你可以使用通常的 kill 方法来完成它,或者使用这个命令来很好地完成它:gpg-connect-agent reloadagent /bye
  • @inetknght 我听到了,我自己并不是新 gpg 架构的忠实粉丝。我更喜欢使用单一二进制方法来拥有多个执行专门操作的可执行文件(例如,从密钥服务器获取密钥的密钥服务器/目录管理器)、gpg-agent 等都与 gpg 对话,而不是只拥有一个功能强大的 gpg 二进制文件。
  • 感谢您的概述。经过一番挖掘,我找到了答案,但这是一个相当笨拙的答案:unix.stackexchange.com/questions/280879/…
【解决方案2】:

根据https://wiki.archlinux.org/index.php/GnuPG#Unattended_passphrase,为了直接向 gpg 提供密码 - 不运行 gpg-agent - 您需要使用以下选项运行:

gpg --passphrase-fd 0 --pinentry-mode loopback ...

您需要在运行此命令后立即在控制台中提供密码。输入时不会显示密码提示,但您会看到输入的密码。

要在键入时隐藏密码,您可以将命令包装在 stty 中:

stty -echo ; gpg ... ; stty echo

我使用 GnuPG v. 2.2.4 对此进行了测试:杀死 gpg-agent,粉碎 /usr/bin/gpg-agent,然后按上述方式运行。效果很好。

【讨论】:

  • 使用 GNuPG 2.2.7 和 --passphrase-fd 0 --pinentry-mode loopback 对我不起作用:Password: gpg: failed to start agent '/usr/local/bin/gpg-agent': No such file or directory // gpg: can't connect to the agent: No such file or directory // gpg: problem with the agent: No agent running
  • 您提到的文档(无人值守密码)确实说 “如果 gpg-agent 进程正在运行以使更改生效,请重新启动它。” 。这似乎意味着gpg-agent 仍然充当输入的接收器(通过控制台而不是 GUI),并且它将通过套接字传递。对此zeitgeist 有何感想?
  • @CraigHicks 正如我所写:我粉碎了 gpg-agent 可执行文件并将其删除。此后 gpg-agent 无法运行,因此它不能用作输入受体。