在终端使用SSH和GPG时,禁止GNOME在GUI中询问密码。

自从我安装了Ubuntu Desktop 16.10 Gnome(之前是15.10),我一直对一个问题感到烦恼,就是每当我尝试在终端中添加SSH密钥或导入GPG密钥时,都会弹出一个GUI弹窗要求输入密码。
对于SSH,我通过在终端上启动一个新的代理然后尝试添加密钥来解决这个问题。最后,它会在TTY中要求我输入密码,而不是在GUI中。
至于GPG,我刚开始学习,所以不确定如何解决这个问题。
有没有办法可以禁用这个功能,并在从TTY访问时要求在TTY中输入密码?
我已经阅读了this问题中的答案,但那是关于ubuntu 12.04的,而且前两个答案对我没有起作用。

1最后一个答案怎么样?http://askubuntu.com/a/806006/158442 - muru
2@guntbert:OP不想禁用SSH和/或GPG代理。他希望在终端上出现密码对话框,而不是在新的X窗口中,当请求SSH/GPG密钥访问的应用程序在终端应用程序内运行时。 - David Foerster
3对于简单的gpg解密命令,请使用 gpg --pinentry-mode loopback -d criptedfile.txt.gpg -o file.txt,它将在命令行中询问密码。无需重新配置。 - DrBeco
1你的意思是,"如何禁用图形用户界面提示,并且只在命令行/终端直接询问,而不使用任何图形用户界面代理程序?" - Thomas Ward
2个回答

SSH和GPG使用所谓的“代理”来缓存解密的私钥,这样用户就不必一直输入密码。默认情况下,它们使用程序pinentry来实现此功能。
在我们继续之前,请确保您的系统上有一个命令行pin entry程序的示例。在Ubuntu的软件仓库中,我们有pinentry-curses(自古以来)和pinentry-tty(自Xenial以来),但它们不是默认安装的。你可以从相同名称的软件包获取它:
sudo apt install pinentry-curses

设置不同的PIN码输入程序

您可以通过以下两种方式调整用于PIN码输入的程序:

(每个用户)在您的~/.gnupg/gpg-agent.conf文件中设置pinentry-program为命令行的PIN输入程序,例如:
pinentry-program /usr/bin/pinentry-curses
您需要重新启动代理或重新加载其配置:
gpg-connect-agent <<< RELOADAGENT

(系统范围内)在包括Ubuntu在内的所有常见Linux发行版中,默认的pinentry程序实际上是一个符号链接,指向实际的PIN输入程序。这个符号链接的目标由update-alternatives系统管理。您可以使用它将链接目标更改为命令行的PIN输入程序:
sudo update-alternatives --config pinentry

根据终端的可用性选择PIN输入程序

这两种方法的缺点是,如果SSH或GPG从没有终端的程序中调用(例如图形SFTP客户端或邮件用户代理),您将无法使用命令行PIN输入。更好的方法是,只有在X服务器可用且终端不可用时才使用图形PIN输入程序。为此,我们需要一个小的包装脚本,在延迟到正确的PIN输入程序之前分析环境。

假设我们在~/.local/bin/my-smart-pinentry中有以下可执行shell脚本:

#!/bin/sh
set -eu

# Configuration -- adjust these to your liking
PINENTRY_TERMINAL='/usr/bin/pinentry-curses'
PINENTRY_X11='/usr/bin/pinentry-x11'

# Action happens below!
if [ -n "${DISPLAY-}" -a -z "${TERM-}" ]; then
    exec "$PINENTRY_X11" "$@"
else
    exec "$PINENTRY_TERMINAL" "$@"
fi

要将此包装器用作密码输入“程序”,您可以使用上面提到的每个用户方法。您还可以将其添加到“update-alternatives”数据库中。

如果有人像我一样使用更新版本,并在(K)ubuntu 20.04 LTS Focal中使用GPG v2.2.19,则有一个更简单的解决方案。我只需要添加--pinentry-mode loopback,它就开始在TTY中要求密码了。我不需要安装任何东西。例如:
gpg --pinentry-mode loopback --export-secret-keys -a | less