Jun 13

有时使用某个应用程序的时候,你需要非常频繁地使用你的 Gnu PG 密钥,这就意味着你需要多次输入密匙解密口令。相当多的应用程序支持将口令(密码)缓存起来方便用户使用。但是出于安全的目的,却不能让缓存的口令(密码)在多个程序之间交叉使用。不过,Gnu PG 提供了很安全的密码缓存方式,也即 Gnu PG 的代理 gpg-agent。通过它,多个应用程序可以共用 Gnu PG 密匙的解密口令。如果你在使用某个应用程序的时候输入了密匙解密口令,其他应用程序可以在一段时间内不用再请求输入口令也能解密 Gnu PG 密钥。下面就来谈谈如何设置 Gnu PG 的代理。

尽管我们不谈论 Gnu PG 公匙、密匙的生成与使用过程,但是使用 Gnu PG,第一步当然是安装它:
$ sudo yum install gnupg
通常,Gnu PG 程序本身就有代理功能。不过在图形界面下,Gnu PG 的代理功能需要用 pinentry 来开启,所以需要先在 Linux 中安装 pinentry 程序。
$ sudo yum install pinentry-gtk 
现在创建 gpg-agent 的配置文件:
$ cat > ~/.gnupg/gpg-agent.conf << EOF 

# PIN entry Program
#pinentry-program /usr/bin/pinentry-curses
#pinentry-program /usr/bin/pinentry-qt4
#pinentry-program /usr/bin/pinentry-kwallet
pinentry-program /usr/bin/pinentry-gtk-2
# Keyboard control
no-grab
# Cache timeout: 3 hours
default-cache-ttl 10800
#default-cache-ttl-ssh 10800

EOF
这个配置指明了 pinentry 程序、口令缓存的超时时间等等。接着激活 Gnu PG 的代理能力,这只要使用下面这一行即可
$ echo "gpg-agent" >> ~/.gnupg/gpg.conf
这一行告诉 Gnu PG 在需要密码时使用 gpg-agent,但前提是需要 gpg-agent 事先已经工作。运行 gpg-agent 的方法很简单:
$ eval $(gpg-agent --daemon)
停止 gpg-agent 的方法是:
$ pkill -u "$USER" gpg-agent
 
为了让 gpg-agent 的使用更加方便,我们自然希望它能够随机器启动而自动工作,这可通过在 /etc/profile.d/ 中作如下的配置来实现
$ sudo cat > /etc/profile.d/gpg-agent.sh << EOF

#!/bin/sh

envfile="${HOME}/.gnupg/gpg-agent.env"
if test -f "$envfile" && kill -0 $(grep GPG_AGENT_INFO “$envfile" |cut -d: -f 2) 2>/dev/null; then
     eval "$(cat :$envfile")"
else
     eval "$(gpg-agent --daemon --write-env-file "$envfile")"
fi
export GPG_AGENT_INFO # the env file does not contain the export statement

EOF

$ sudo chmod 755 /etc/profile.d/gpg-agent.sh
以上的设置使得每位登录 Linux 的用户自动启用 gpg-agent。一般而言,一个会话只允许开启一个 gpg-agent 进程。关于这一点,我们可以从上面的配置中可以看到。如果我们只希望为某个用户启用 gpg-agent,可在 ~/.xprofile、~/.xsession 或者 ~/.xinitrc 中添加下面这一行,这取决于我们使用的图形界面的启动方式,例如:
$ echo 'eval "$(gpg-agent --daemon)"' >> ~/.xprofile
如果用户不使用图形界面的话,也可以将上面这一行写入 ~/.bash_profile。通过前面这些设置便能自动启动 gpg-agent 了。关于 gpg-agent 的更多设置,请自行参看 gpg-agent 的手册页
$ man gpg-agent
 
实际上,从手册页中可以看到,gpg-agent 还可以作为 ssh-agent,这只需要在命令行 gpg-agent 中增加 --enable-ssh-support 选项即可。下面给出一个自动作为 ssh-agent 与 gpg-agent 的配置:
$ cat >> ~/.bash_profile << EOF

#!/bin/sh

# Start the GnuPG agent and enable OpenSSH agent emulation
gnupginf="${HOME}/.gpg-agent-info"

if pgrep -u "${USER}" gpg-agent >/dev/null 2>&1; then
    eval `cat $gnupginf`
    eval `cut -d= -f1 $gnupginf | xargs echo export`
else
    eval `gpg-agent -s --enable-ssh-support --daemon`
fi 

EOF
 
值得指出的是,Gnome 桌面自身提供的 Gnome-keyring 也整合了 gpg-agent 功能,这取决于 Gnome-keyring 包编译过程有没有开启 gpg-agent 选项。如果我们想禁用 Gnome-keyring 的 gpg-agent 功能,除去修改源码的编译选项之外,还可作如下操作来实现
$ cp /etc/xdg/autostart/gnome-keyring-gpg.desktop ~/.config/autostart/gnome-keyring-gpg.desktop
$ echo "X-GNOME-Autostart-enabled=false" >> ~/.config/autostart/gnome-keyring-gpg.desktop
实际上,上面的操作与如下的半图形化操作相同:
$ gnome-session-properties
在随后出现的图形框中勾选掉 gnome-keyring-gpg 功能。如果只是想临时禁用 Gnome-keyring,可执行
$ sudo pkill gnome-keyring