GPG in Emacs

发布: 2021-11-26   更新: 2023-09-02   标签: tips GPG

文章目录

Pretty Good Privacy (PGP) 是一款诞生于 1991 年的,一款用于认证、加密的一款软件,现如今已经有了标准化协议 OpenPGP,最常用的实现是 GnuPG,一般提到 GPG 时都是指的 GnuPG。

笔者在保存一些私人文件像日记、密码等时,就会用 GPG 格式的文件来保存。这篇文章就来介绍下 Emacs 对 GPG 的支持,关于如何创建 GPG key,读者可参考 GPG入门教程 by 阮一峰

生产密钥

如果读者是第一次使用 GPG,需要先生成一个密钥:

1
gpg --gen-key

之后根据提示来操作就可以了。

密码输入

为了提高 key 安全系数,一般推荐在创建 key 时设置一个密码,这样即使密钥丢了,别人也无法使用。

但是每次 输入密码显得有些繁琐,解决方式是让 gpg-agent 这个进程记住密码,这样只需在系统第一次使用时输入即可。为了让 Emacs 能在首次使用 GPG 时,捕获密码输入框,在 minibuffer 中输入密码,需要做如下的配置:

  1. 修改 agent 的配置文件

    1
    2
    3
    4
    5
    6
    7
    
    # cat ~/.gnupg/gpg-agent.conf
    
    allow-emacs-pinentry
    allow-loopback-pinentry
    
    # 之后重新加载即可
    gpgconf --reload gpg-agent
  2. 安装 pinentry 包,配置 loopback,
  3. 启动 pinentry server,参考配置

    1
    2
    3
    4
    
    (use-package pinentry
    :config
    (setq epa-pinentry-mode 'loopback)
    (pinentry-start))

笔者之前一直很好奇为什么这么复杂,pinentry 是什么东西?为什么需要它?我只是想输入一个密码而已呀。 直到写这篇文章,我才彻底了解 pinentry 进程的作用:

它会让用户输入的密码不会因内存不足而换出到磁盘

说到底还是安全问题,更多技术细节可参考:pinentry-curses(1) man page

文件操作

GPG 格式的文件是一种二进制文件,一般的编辑器是无法打开的,但 Emacs 对 GPG 提供了非常方便的支持,比如创建一个名为 password.org.gpg 的文件,保存时 Emacs 会自动弹出选择框,让用户选择加密的公钥。

1
2
3
4
5
6
7
Select recipients for encryption.
If no one is selected, symmetric encryption will be performed.
- ‘m’ to mark a key on the line
- ‘u’ to unmark a key on the line
[Cancel][OK]

  u D3026E5C08A0BAB4 Jiacai Liu <xxx@gmail.com>

而且,这个文件的 major mode 也能正确识别为 org mode,这样就可以非常方便的编辑 GPG 文件。与此同理,可以方便地创建任何格式的 GPG 文件,比如: diary.md.gpg ,重新打开文件时,Emacs 会自动解密,并设置相应的 major mode。

EasyPG

Emacs 自带的 EasyPG 包对常用 GPG 命令都提供了相应函数的支持:

  • epa-sign-file
  • epa-verify-file
  • epa-encrypt-<file/region>
  • epa-decrypt-<file/region>
  • epa-import-keys
  • epa-export-keys
  • epa-list-keys
  • epa-list-secret-keys
  • epa-delete-keys

EasyPG 还提供了与 Dired 的集成:

key bindingdescription
: dDecrypt
: eEncrypt
: sSign
: vverify

Git 集成

Git 对 GPG 这种二进制文件有特殊的支持,可以转化为文本的方式,这样就能非常方便的进行 diff、merge 了。

1
2
git config --global diff.gpg.textconv "gpg --no-tty --decrypt"
echo "*.gpg filter=gpg diff=gpg" > ~/.gitattributes

导入导出

可以用下面的命令将密钥导出,便于在其他机器上使用

1
gpg --armor --output private-key.txt --export-secret-keys

如果有密码的话,会弹出输入对话框。生成的 private-key.txt 中包含公钥。

在另一个机器上,可以用如下命令将密钥导入。

1
gpg --import [密钥文件]

默认导入的密钥是没被信任的,可以用如下命令来将密钥设置为永久可信:

1
2
3
4
gpg --edit-key [key-id]
gpg> trust
> 5
> save

软件签名校验

在互联网上下载软件时,网站一般会提供一些校验手段,保证软件没有被篡改过,常用的手段有:

  • PGP,签名文件一般为 asc 或 sig
  • 文件哈希,常用的算法有 MD5、SHA512

比如在 Apache Lucene 下载页就提供了这两种验证文件,在下载了源文件与签名 PGP 文件到同一目录后,执行 epa-verify-file 即可验证。当然,这需要事先导入签名者的公钥,具体可以参考:

但是有一点,用户无法验证该公钥的真实性,毕竟 keyserver 是谁都可以发布的,想要真正的安全,只能去线下亲自找那个人来交换公钥,但现实是没人这么做。

弦外之音

尽管 GPG 出现的时间很久,但互联网上每隔一段时间都会出现批评它的文章,比如:

但目前为止,GPG 还没有替代品。没有 Emacs 的话,很难想象如何去方便、快捷地操作 GPG。

GnuPG 在 2022-01-02 发布了一篇文章 a-new-future-for-gnupg,介绍了它最新的发展情况,主要给企业提供加密方案,而且已经成立公司来运营,并且已经盈利,说不准将来哪一天 GPG 能迎来新春?

参考



收听方式

反馈