GnuPG

来自 ArchWiki
(重定向自 Gpg)

根据 官方网站

GnuPG 是 OpenPGP 标准的完整且免费的实现,该标准由 RFC 4880(也称为 PGP)定义。 GnuPG 允许您加密和签名您的数据和通信;它具有通用的密钥管理系统,以及用于各种公钥目录的访问模块。 GnuPG,也称为 GPG,是一个命令行工具,具有与其他应用程序轻松集成的功能。 提供了大量的前端应用程序和库。 GnuPG 还提供对 S/MIME 和 Secure Shell (ssh) 的支持。
警告: GnuPG 最初是 OpenPGP 格式的实现。 然而,近年来,其维护者积极地偏离了 OpenPGP 标准化工作,并以 GnuPG 特定的方式单独扩展了该格式(参见 draft-koch-librepgp)。 自 2.4 版本以来,这些更改导致与其他实现的兼容性问题。 请参阅 #OpenPGP 兼容性

安装

安装 gnupg 软件包。

这也将安装 pinentry,这是一组简单的 PIN 或密码输入对话框,GnuPG 使用它们进行密码输入。 shell 脚本 /usr/bin/pinentry 确定使用哪个 pinentry 对话框,顺序如 #pinentry 中所述。

如果您想使用图形前端或与 GnuPG 集成的程序,请参阅 应用程序列表/安全#加密、签名、隐写术

配置

Home 目录

GnuPG home 目录是 GnuPG 套件存储其密钥环和私钥,以及从中读取配置的位置。 默认情况下,使用的路径是 ~/.gnupg。 有两种方法可以覆盖此设置

  • 设置 $GNUPGHOME 环境变量
  • 使用 --homedir 参数,例如 $ gpg --homedir path/to/dir [1]

默认情况下,home 目录的 权限 设置为 700,它包含的文件权限设置为 600。 只有目录的所有者才有权读取、写入和访问文件。 这是为了安全目的,不应更改。 如果此目录或其中任何文件未遵循此安全措施,您将收到有关不安全文件和 home 目录权限的警告。

配置文件

GnuPG 的所有行为都可以通过命令行参数配置。 对于您希望作为默认值的参数,您可以将它们添加到相应的配置文件中

  • gpg 检查 gnupg_home/gpg.conf(用户)和 /etc/gnupg/gpg.conf(全局) [2]。 由于 gpg 是 GnuPG 的主要入口点,因此大多数感兴趣的配置都将在此处。 有关可能的选项,请参阅 GPG 选项
  • dirmngr 检查 gnupg_home/dirmngr.conf/etc/gnupg/dirmngr.confdirmngr 是一个由 gpg 内部调用的程序,用于访问 PGP 密钥服务器 [3]。 有关可能的选项,请参阅 Dirmngr 选项

这两个配置文件涵盖了常见的用例,但 GnuPG 套件中还有更多具有自己选项的辅助程序。 有关完整列表,请参阅 GnuPG 手册

创建所需的文件,并将它们的权限设置为 600,如 #Home 目录 中讨论的那样。

将您想要的任何长选项添加到这些文件中。 不要写两个破折号,而只需写选项的名称和所需的参数。 例如,要使 GnuPG 始终使用特定路径的密钥环,就像它被调用为 gpg --no-default-keyring --keyring keyring-path ... 一样

gnupg_home/gpg.conf (or /etc/gnupg/gpg.conf)
no-default-keyring
keyring keyring-path

其他示例可以在 #参见 中找到。

此外,pacman 使用一组不同的配置文件进行软件包签名验证。 有关详细信息,请参阅 Pacman/软件包签名

新用户的默认选项

如果您想为新用户设置一些默认选项,请将配置文件放在 /etc/skel/.gnupg/ 中。 当在系统中添加新用户时,此处的文件将被复制到其 GnuPG home 目录。 还有一个名为 addgnupghome 的简单脚本,您可以使用它为现有用户创建新的 GnuPG home 目录

# addgnupghome user1 user2

这将添加相应的 /home/user1/.gnupg//home/user2/.gnupg/,并将文件从骨架目录复制到其中。 具有现有 GnuPG home 目录的用户将被简单地跳过。

用法

注意
  • 每当命令中需要 user-id 时,都可以使用您的密钥 ID、指纹、部分名称或电子邮件地址等来指定。 GnuPG 在这方面很灵活。
  • 每当需要 key-id 时,可以通过向命令添加 --keyid-format=long 标志来找到它。 例如,要显示主密钥,请运行 gpg --list-secret-keys --keyid-format=long user-idkey-id 是与 sec 在同一行提供的十六进制哈希。

创建密钥对

通过在终端中键入以下内容来生成密钥对

$ gpg --full-gen-key
警告: 当使用 --full-gen-key 时,生成的密钥将声明 AEAD 机制,这不被其他 OpenPGP 实现所理解。 要在密钥创建后禁用此功能,请参阅 #禁用不支持的 AEAD 机制

还可以将 --expert 选项添加到命令行,以访问更多密码,特别是像 Curve448 这样的一些较新的椭圆曲线

该命令将提示您回答几个问题。 对于一般用途,大多数人会想要

  • 签名和加密密钥的默认ECC(签名和加密)
  • 默认 Curve 25519 以使用 Curve25519Ed25519
  • 过期日期:一年对于普通用户来说已经足够了。 这样,即使密钥环的访问权限丢失,它也会让其他人知道它不再有效。 在稍后阶段,如果需要,可以延长过期日期,而无需重新发布新密钥。
  • 您的姓名和电子邮件地址。 您稍后可以向同一密钥添加多个身份(例如,如果您有多个想要与此密钥关联的电子邮件地址)。
  • 可选注释。 由于注释字段的语义 未明确定义,因此它对于标识的价值有限。
  • 安全密码,在 安全#选择安全密码 中找到一些指南。
注意: 您在此处输入的姓名和电子邮件地址将对导入您的密钥的任何人可见。
提示: 更简单的 --gen-key 选项使用密钥密码、大小和过期的默认参数,并且仅询问真实姓名电子邮件地址

列出密钥

要列出您的公钥环中的密钥

$ gpg --list-keys

要列出您的私钥环中的密钥

$ gpg --list-secret-keys

导出您的公钥

GnuPG 的主要用途是通过公钥密码术确保交换消息的机密性。 使用它,每个用户分发其密钥环的公钥,其他人可以使用它来加密发送给用户的消息。 私钥必须始终保密,否则机密性将被破坏。 有关消息交换的示例,请参阅 维基百科:公钥密码术

因此,为了让其他人向您发送加密消息,他们需要您的公钥。

要生成用户公钥的 ASCII 版本到文件 public-key.asc(例如,通过电子邮件分发它)

$ gpg --export --armor --output public-key.asc user-id

或者,或作为补充,您可以使用 密钥服务器 来共享您的密钥。

提示
  • 添加 --no-emit-version 以避免打印版本号,或将相应的设置添加到您的 gpg.conf 中。
  • 您可以省略 user-id 以导出密钥环中的所有公钥。 如果您想一次共享多个身份,或者导入到另一个应用程序(例如 Thunderbird)中,这将非常有用。

导入公钥

为了加密发送给其他人的消息,以及验证他们的签名,您需要他们的公钥。 要将文件名为 public-key.asc 的公钥导入到您的公钥环中

$ gpg --import public-key.asc

或者,使用密钥服务器查找公钥。

如果您希望导入密钥 ID 以安装特定的 Arch Linux 软件包,请参阅 pacman/软件包签名#管理密钥环Makepkg#签名检查

使用密钥服务器

发送密钥

您可以将您的密钥注册到公共 PGP 密钥服务器,以便其他人可以检索它,而无需直接与您联系

$ gpg --send-keys key-id
警告: 有些密钥服务器提交的密钥无法删除。 MIT PGP 公钥服务器 FAQ 中解释了一些原因。
注意: 关联的电子邮件地址一旦公开,可能会成为垃圾邮件发送者的目标,在这种情况下,可能需要反垃圾邮件过滤。

搜索和接收密钥

要在密钥服务器上查找密钥的详细信息,而不导入它,请执行以下操作

$ gpg --search-keys user-id

要从密钥服务器导入密钥

$ gpg --receive-keys key-id

要使用密钥服务器刷新/更新密钥链到最新版本

$ gpg --refresh-keys
警告
  • 您应该通过将其指纹与所有者在独立来源(例如,直接联系该人)上发布的指纹进行比较来验证检索到的公钥的真实性。 有关更多信息,请参阅 维基百科:公钥指纹
  • 建议在接收密钥时使用长密钥 ID 或完整指纹。 使用短 ID 可能会遇到冲突。 将导入所有具有短 ID 的密钥,有关此类示例,请参阅 在野外发现的伪造密钥
提示:GPG 配置文件 中添加 auto-key-retrieve 将在需要时自动从密钥服务器获取密钥。 这不会损害安全性,但可以被认为是侵犯隐私; 请参阅 gpg(1) § auto-key-retrieve 中的“web bug”。

密钥服务器

有关 OpenPGP 密钥服务器及其功能的概述,请参阅 OpenPGP#密钥服务器

可以使用 配置文件 之一中的 keyserver 选项指定备用密钥服务器,例如

~/.gnupg/dirmngr.conf
keyserver hkp://keyserver.ubuntu.com

当常规服务器无法正常工作时,临时使用另一个服务器很方便。 例如,可以通过以下方式实现

$ gpg --keyserver hkps://keys.openpgp.org/ --search-keys user-id
提示
  • 如果您遇到密钥服务器故障,您可能需要事先检查您的 DNS 和您的解析器配置或其日志(例如 systemd-resolved)。
  • 如果接收失败并显示消息 gpg: keyserver receive failed: Connection refused,请尝试使用其他 DNS 服务器。
  • 如果连接到密钥服务器失败并显示 gpg: keyserver receive failed: Server indicated a failure,您可能需要配置 gpg 以使用备用端口。 例如,要在 Ubuntu 的密钥服务器上使用端口 80,请使用 keyserver hkp://keyserver.ubuntu.com:80
  • 您可以使用 TorTor#Torsocks 连接到密钥服务器。 或使用 --use-tor 命令行选项。 有关更多信息,请参阅 [4]
  • 您可以通过设置 http_proxy 环境变量 并在 dirmngr.conf 中设置 honor-http-proxy,使用代理连接到密钥服务器。 或者,在配置文件中设置 http-proxy host[:port] 以覆盖同名的环境变量。 重启 dirmngr.service 用户服务 以使更改生效。

Web Key Directory

有关概述,请参阅 OpenPGP#Web 密钥目录

使用 WKD 查找证书

当加密到电子邮件地址(例如 user@example.org)时,如果本地密钥环中尚不存在公钥,GnuPG (>=2.1.16) 将通过 HTTPS 查询域 (example.com) 以获取公钥 OpenPGP 密钥。 如果本地密钥环中没有此电子邮件地址的密钥,则选项 --auto-key-locate 将默认使用 WKD 协议查找密钥

$ gpg --recipient user@example.org --auto-key-locate --encrypt doc

创建 WKD

如果您自己控制电子邮件地址的域,您可以按照 本指南 为您的域启用 WKD。

加密和解密

非对称加密

您需要在加密(选项 -e/--encrypt)文件或消息给该收件人(选项 -r/--recipient)之前 导入用户的公钥。 此外,如果您尚未这样做,则需要 创建密钥对

要加密文件名为 doc 的文件,请使用

$ gpg --recipient user-id --encrypt doc

要解密(选项 -d/--decrypt)使用您的公钥加密的文件名为 doc.gpg 的文件,请使用

$ gpg --output doc --decrypt doc.gpg

gpg 将提示您输入密码,然后解密并将数据从 doc.gpg 写入到 doc。 如果您省略 -o/--output 选项,gpg 会将解密后的数据写入到标准输出。

提示
  • 添加 --armor 以使用 ASCII 编码加密文件,适用于复制和粘贴文本格式的消息。
  • 使用 -R user-id--hidden-recipient user-id 而不是 -r 以不将收件人密钥 ID 放在加密消息中。 这有助于隐藏消息的接收者,并且是针对流量分析的有限对策。
  • 添加 --no-emit-version 以避免打印版本号,或将相应的设置添加到您的配置文件。
  • 您可以使用 GnuPG 通过使用您自己的用户 ID 作为收件人或使用 --default-recipient-self 标志来加密您的敏感文档; 但是,您一次只能执行一个文件,尽管您可以始终将各种文件打包成 tarball,然后加密 tarball。 如果您想加密目录或整个文件系统,另请参阅 静态数据加密#可用方法

对称加密

对称加密不需要生成密钥对,可以用来简单地使用密码加密数据。 只需使用 -c/--symmetric 执行对称加密

$ gpg -c doc

以下示例

  • 使用密码和对称密码加密 doc
  • 使用 AES-256 密码算法加密数据
  • 使用 SHA-512 摘要算法来搅乱密码并生成加密密钥
  • 将密码搅乱 65536 次迭代
$ gpg -c --s2k-cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-count 65536 doc

要使用密码解密对称加密的 doc.gpg 并将解密后的内容输出到与 doc 相同的目录中,请执行以下操作

$ gpg --output doc --decrypt doc.gpg

目录

可以使用 gpgtar(1) 完成加密/解密目录。

加密

$ gpgtar -c -o dir.gpg dir

解密

$ gpgtar -d dir.gpg

密钥维护

备份您的私钥

要备份您的私钥,请执行以下操作

$ gpg --export-secret-keys --armor --output private-key.asc user-id

如果私钥受密码保护,则导出的密钥文件将受到相同的密码保护。

GnuPG 可能会要求您输入密钥的密码。 这是必需的,因为私钥的内部保护方法与 OpenPGP 协议指定的保护方法不同。[5]

警告
  • 密码通常是保护您的密钥的最薄弱环节。 将私钥放在不同系统/设备上的安全位置,例如锁定的容器或加密驱动器。 这是您在发生驱动器故障、被盗或更糟情况时重新获得密钥环控制权的唯一安全保障。
  • 这种备份密钥的方法有一些安全限制。 有关可能更安全的备份和导入密钥的方法,请参阅 VHSblog 上的 私下移动 GPG 密钥 文章,使用 gpg

要导入您的私钥备份

$ gpg --import private-key.asc
提示: Paperkey 可用于将私钥导出为人类可读的文本或机器可读的条形码,这些条形码可以打印在纸上并存档。

备份您的吊销证书

吊销证书是为新生成的密钥自动生成的。 默认情况下,这些证书位于 ~/.gnupg/openpgp-revocs.d/ 中。 证书的文件名是它将吊销的密钥的指纹。 用户也可以稍后使用以下命令手动生成吊销证书

$ gpg --gen-revoke --armor --output revcert.asc user-id

如果密钥丢失或泄露,可以使用此证书 吊销密钥。 如果您不再有权访问私钥,因此无法使用上述命令生成新的吊销证书,则备份将非常有用。 它足够短,可以打印出来并在必要时手动输入。

警告: 任何有权访问吊销证书的人都可以公开吊销密钥,此操作无法撤消。 像保护您的密钥一样保护您的吊销证书。

编辑您的密钥

运行 gpg --edit-key user-id 命令将显示一个菜单,您可以从中执行大多数与密钥管理相关的任务。

在编辑密钥子菜单中键入 help 以显示完整命令列表。 一些有用的命令

> passwd       # change the passphrase
> clean        # compact any user ID that is no longer usable (e.g revoked or expired)
> revkey       # revoke a key
> addkey       # add a subkey to this key
> expire       # change the key expiration time
> adduid       # add additional names, comments, and email addresses
> addphoto     # add photo to key (must be JPG, 240x288 recommended, enter full path to image when prompted)
提示: 如果您有多个电子邮件帐户,您可以使用 adduid 命令将每个帐户添加为身份。 然后,您可以将您最喜欢的帐户设置为 primary

导出子密钥

如果您计划在多个设备上使用同一密钥,您可能需要剥离您的主密钥,并且仅在不太安全的系统上保留最少的加密子密钥。

首先,找出您要导出的子密钥。

$ gpg --list-secret-keys --with-subkey-fingerprint

仅选择要导出的子密钥。

$ gpg --armor --export-secret-subkeys subkey-id! > /tmp/subkey.asc
警告: 如果您忘记添加 !,则将导出您的所有子密钥。

此时您可以停止,但这很可能也是更改密码的好主意。 将密钥导入到临时文件夹中。

$ gpg --homedir /tmp/gpg --import /tmp/subkey.asc
$ gpg --homedir /tmp/gpg --edit-key user-id
> passwd
> save
$ gpg --homedir /tmp/gpg --armor --export-secret-subkeys subkey-id! > /tmp/subkey.altpass.asc
注意: 您将收到一条警告,指出主密钥不可用且密码未更改,但这可以安全地忽略,因为子密钥密码已更改。

此时,您现在可以在其他设备上使用 /tmp/subkey.altpass.asc

延长过期日期

警告: 除非您有充分的理由,否则永远不要删除您过期或吊销的子密钥。 这样做会导致您失去解密使用旧子密钥加密的文件的能力。 请删除其他用户的过期或吊销密钥以清理您的密钥环。

最好在您的子密钥上设置过期日期,这样,如果您丢失了对密钥的访问权限(例如,您忘记了密码),该密钥将不会继续被其他人无限期地使用。 当密钥过期时,延长过期日期相对简单

$ gpg --edit-key user-id
> expire

系统将提示您输入新的过期日期,以及您的密钥的密码,该密码用于签署新的过期日期。

提示: 可以通过输入 YYYY-MM-DD 格式的日期或 YYYYMMDDThhmmss 格式的时间戳作为过期值来指定确切的过期日期和时间。

对任何其他已过期的子密钥重复此操作

> key 1
> expire

最后,保存更改并退出

> save

将其更新到密钥服务器。

$ gpg --keyserver keyserver.ubuntu.com --send-keys key-id

或者,如果您在多台计算机上使用此密钥,您可以导出公钥(带有新的签名过期日期),并在这些计算机上导入它

$ gpg --export --output pubkey.gpg user-id
$ gpg --import pubkey.gpg

无需重新导出您的密钥或更新您的备份:主密钥本身永不过期,并且留在公钥和子密钥上的过期日期签名是您所需要的全部。

轮换子密钥

警告: 除非您有充分的理由,否则永远不要删除您过期或吊销的子密钥。 这样做会导致您失去解密使用旧子密钥加密的文件的能力。 请删除其他用户的过期或吊销密钥以清理您的密钥环。

或者,如果您更喜欢在子密钥过期后完全停止使用它们,您可以创建新的子密钥。 请提前几周执行此操作,以便其他人更新他们的密钥环。

提示: 您无需仅仅因为密钥已过期就创建新密钥。 您可以延长过期日期,请参阅 #延长过期日期

创建新的子密钥(对签名和加密密钥都重复此操作)

$ gpg --edit-key user-id
> addkey

并回答它提出的以下问题(有关建议的设置,请参阅 #创建密钥对)。

保存更改

> save

将其更新到密钥服务器。

$ gpg --keyserver pgp.mit.edu --send-keys user-id

您还需要导出私钥的新副本以进行备份。 有关如何执行此操作的详细信息,请参阅 #备份您的私钥

提示: 吊销过期的子密钥是不必要的,并且可以说是糟糕的形式。 如果您不断吊销密钥,可能会导致其他人对您缺乏信心。

吊销密钥

如果密钥泄露、被取代、不再使用或您忘记了密码,则应执行密钥吊销。 这是通过将密钥与密钥的吊销证书合并来完成的。

如果您不再有权访问您的密钥对,请首先 导入公钥 以导入您自己的密钥。

然后,要吊销密钥,请导入在 #备份您的吊销证书 中保存的文件

$ gpg --import revcert.asc

现在需要公开吊销。 如果您过去使用过公共 PGP 服务器,请 使用密钥服务器 将吊销的密钥发送到公共 PGP 服务器,否则,将吊销的密钥导出到文件并将其分发给您的通信伙伴。

签名

签名认证文档并添加时间戳。 如果文档被修改,签名验证将失败。 与使用接收者公钥加密文档的加密不同,签名是使用发送者的私钥创建的。 然后,签名文档的接收者使用发送者的公钥验证签名。

创建签名

签名文件

要签名文件,请使用 -s/--sign 标志

$ gpg --output doc.sig --sign doc

doc.sig 包含原始文件 doc 的压缩内容和二进制格式的签名,但该文件未加密。 但是,您可以将签名与 加密 结合使用。

明文签名文件或消息

要签名文件而不将其压缩为二进制格式,请使用

$ gpg --output doc.sig --clearsign doc

在此,原始文件 doc 的内容和签名都以人类可读的形式存储在 doc.sig 中。

制作分离签名

要创建要与文档或文件本身分开分发的单独签名文件,请使用 --detach-sig 标志

$ gpg --output doc.sig --detach-sig doc

在此,签名存储在 doc.sig 中,但 doc 的内容未存储在其中。 此方法通常用于分发软件项目,以允许用户验证程序是否已被第三方修改。

验证签名

要验证签名,请使用 --verify 标志

$ gpg --verify doc.sig

其中 doc.sig 是包含您要验证的签名的签名文件。

如果您要验证分离签名,则在验证时签名数据文件和签名文件都必须存在。例如,要验证 Arch Linux 的最新 iso,您需要执行以下操作

$ gpg --verify archlinux-version.iso.sig

其中 archlinux-version.iso 必须位于同一目录下。

您也可以使用第二个参数指定签名数据文件

$ gpg --verify archlinux-version.iso.sig /path/to/archlinux-version.iso

如果文件除了签名外还被加密,只需 解密 该文件,其签名也将被验证。

gpg-agent

此文章或章节需要扩充。

原因: 记录 keyboxd.socketkeyboxd.service[6] (在 讨论页:GnuPG 中讨论)

gpg-agent 主要用作守护进程,用于请求和缓存密钥链的密码。当从外部程序(如邮件客户端)使用 GnuPG 时,这非常有用。gnupg 附带 systemd 用户 套接字,默认情况下已启用。这些套接字是 gpg-agent.socketgpg-agent-extra.socketgpg-agent-browser.socketgpg-agent-ssh.socketdirmngr.socket

  • gpg-agent.socketgpg 用于连接到 gpg-agent 守护进程。
  • gpg-agent-extra.socket 在本地系统上的预期用途是设置从远程系统转发的 Unix 域套接字。这使得可以在远程系统上使用 gpg,而无需将私钥暴露给远程系统。有关详细信息,请参阅 gpg-agent(1)
  • gpg-agent-browser.socket 允许 Web 浏览器访问 gpg-agent 守护进程。
  • gpg-agent-ssh.socket 可以被 SSH 使用,以缓存由 ssh-add 程序添加的 SSH 密钥。有关必要的配置,请参阅 #SSH 代理
  • dirmngr.socket 启动一个 GnuPG 守护进程,处理与密钥服务器的连接。
注意: 如果您使用非默认的 GnuPG 主目录,您将需要 编辑 所有套接字文件的 ListenStream (参见 systemd.socket(5) § 选项),使其与 gpgconf --list-dirs 一致。套接字名称使用非默认 GnuPG 主目录的哈希值 [7],因此您可以硬编码它,而无需担心它会更改。

配置

gpg-agent 可以通过 ~/.gnupg/gpg-agent.conf 文件进行配置。配置选项在 gpg-agent(1) 中列出。例如,您可以更改未使用密钥的缓存 ttl

~/.gnupg/gpg-agent.conf
default-cache-ttl 3600
提示: 要在整个会话中缓存您的密码短语,请运行以下命令
$ /usr/lib/gnupg/gpg-preset-passphrase --preset XXXXX

其中 XXXXX 是密钥指纹 (keygrip)。您可以在运行 gpg --with-keygrip --list-secret-keys 时获取其值。密码短语将被存储直到 gpg-agent 重新启动。如果您设置了 default-cache-ttl 值,它将优先。

有必要通过使用 --allow-preset-passphrase 启动 gpg-agent 或在 ~/.gnupg/gpg-agent.conf 中设置 allow-preset-passphrase 来允许此密码短语预设。

重新加载代理

更改配置后,使用 gpg-connect-agent 重新加载代理

$ gpg-connect-agent reloadagent /bye

该命令应打印 OK

但是,在某些情况下,仅重新启动可能不足,例如当 keep-screen 已添加到代理配置中时。在这种情况下,您首先需要杀死正在进行的 gpg-agent 进程,然后您可以按照上述说明重新启动它。

pinentry

可以通过 pinentry-program 节配置 gpg-agent,以便在提示用户输入密码短语时使用特定的 pinentry 用户界面。例如

~/.gnupg/gpg-agent.conf
pinentry-program /usr/bin/pinentry-curses

还有其他 pinentry 程序可供选择 - 请参阅 pacman -Ql pinentry | grep /usr/bin/。您可能需要为您选择的 pinentry 程序安装相关的 可选依赖项

提示
注意: 当使用 KDE 时,Secret Service API 集成被禁用,以 防止死锁,以防 KDE Wallet 使用 GnuPG 加密。如果您将 KDE Wallet 与经典的、blowfish 加密的文件一起使用,请通过将 环境变量 PINENTRY_KDE_USE_WALLET 设置为非空值来重新启用 Secret Service API 集成。

在更改配置后,请记住 重新加载代理

缓存密码

max-cache-ttldefault-cache-ttl 定义 gpg-agent 应缓存密码的秒数。要在一个会话中输入一次密码,请将它们设置为非常高的值,例如

gpg-agent.conf
max-cache-ttl 60480000
default-cache-ttl 60480000

对于 SSH 模拟模式下的密码缓存,请设置 default-cache-ttl-sshmax-cache-ttl-ssh,例如

gpg-agent.conf
default-cache-ttl-ssh 60480000
max-cache-ttl-ssh 60480000

无人值守密码短语

从 GnuPG 2.1.0 开始,需要使用 gpg-agent 和 pinentry,这可能会破坏从 STDIN 使用 --passphrase-fd 0 命令行选项管道输入密码短语的向后兼容性。为了获得与旧版本相同类型的功能,必须完成两件事

首先,编辑 gpg-agent 配置以允许环回 pinentry 模式

~/.gnupg/gpg-agent.conf
allow-loopback-pinentry

如果代理正在运行,重新加载代理 以使更改生效。

其次,应用程序需要更新以包含一个命令行参数来使用环回模式,如下所示

$ gpg --pinentry-mode loopback ...

...或者如果这不可能,请将该选项添加到配置中

~/.gnupg/gpg.conf
pinentry-mode loopback
注意: 上游作者指出在 gpg.conf 中设置 pinentry-mode loopback 可能会破坏其他用法,如果可能,应首选使用命令行选项。[9]

SSH 代理

gpg-agent 具有 OpenSSH 代理模拟功能。如果您已经使用 GnuPG 套件,您不妨考虑使用其代理来缓存您的 SSH 密钥。此外,一些用户可能更喜欢 GnuPG 代理提供的 PIN 输入对话框,作为其密码短语管理的一部分。

设置 SSH_AUTH_SOCK

设置 以下变量以与 gpg-agent 而不是默认的 ssh-agent 通信。

SSH_AGENT_PID=""
SSH_AUTH_SOCK="${XDG_RUNTIME_DIR}/gnupg/S.gpg-agent.ssh"
注意
  • 如果您使用脚本来管理您的变量,您也可以取消设置 SSH_AGENT_PID 而不是将其设置为 "",通过 unset SSH_AGENT_PID
  • 如果您手动设置 SSH_AUTH_SOCK,请记住,如果您使用自定义 GNUPGHOME,您的套接字位置可能会有所不同。您可以使用以下 bash 示例,或将 SSH_AUTH_SOCK 更改为 gpgconf --list-dirs agent-ssh-socket 的值。
  • 如果安装了 GNOME Keyring,则必须 禁用 其 ssh 组件。否则,它将覆盖 SSH_AUTH_SOCK

或者,依赖 Bash。这也适用于非标准套接字位置

~/.bashrc
unset SSH_AGENT_PID
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
  export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi
注意: 涉及 gnupg_SSH_AUTH_SOCK_by 变量的测试是针对代理以 gpg-agent --daemon /bin/sh 启动的情况,在这种情况下,shell 从父进程继承 SSH_AUTH_SOCK 变量,gpg-agent [10]

配置 pinentry 以使用正确的 TTY

还要设置 GPG_TTY 并刷新 TTY,以防用户已切换到 X 会话,如 gpg-agent(1) 中所述。例如

~/.bashrc
export GPG_TTY=$(tty)
gpg-connect-agent updatestartuptty /bye >/dev/null

如果您同时使用多个终端,并且希望 gpg-agent 从运行 ssh 命令的同一终端通过 pinentry-curses 请求密码短语,请将以下内容添加到 SSH 配置文件。这将使每次运行 ssh 命令时都刷新 TTY [11]

~/.ssh/config
Match host * exec "gpg-connect-agent UPDATESTARTUPTTY /bye"

请注意,必须设置 GPG_TTY 环境变量才能使其工作。

添加 SSH 密钥

一旦 gpg-agent 正在运行,您可以使用 ssh-add 来批准密钥,遵循与 ssh-agent 相同的步骤。批准的密钥列表存储在 ~/.gnupg/sshcontrol 文件中。

一旦您的密钥被批准,每次需要您的密码短语时,您都会得到一个 pinentry 对话框。有关密码缓存,请参阅 #缓存密码

使用 PGP 密钥进行 SSH 身份验证

您还可以使用您的 PGP 密钥作为 SSH 密钥。这需要具有 Authentication 功能的密钥(请参阅 #自定义功能)。通过使用 PGP 密钥进行 SSH 身份验证,可以获得各种好处,包括

  • 减少密钥维护,因为您将不再需要维护 SSH 密钥。
  • 将身份验证密钥存储在智能卡上的能力。当卡可用时,GnuPG 将自动检测密钥,并将其添加到代理(使用 ssh-add -lssh-add -L 检查)。密钥的注释应类似于:openpgp:key-idcardno:card-id

要检索您的 GPG/SSH 密钥的公钥部分,请运行 gpg --export-ssh-key gpg-key。如果您的密钥具有身份验证能力,但此命令仍然失败并显示“Unusable public key”,请添加 ! 后缀 ([12])。

除非您的 GPG 密钥在密钥卡上,否则您需要将您的密钥添加到 $GNUPGHOME/sshcontrol 以被识别为 SSH 密钥。如果您的密钥在密钥卡上,则其密钥指纹 (keygrip) 将隐式添加到 sshcontrol。否则,请通过以下方式获取您的密钥的密钥指纹 (keygrip)

$ gpg --list-keys --with-keygrip
sub   rsa4096 2018-07-25 [A]
      Keygrip = 1531C8084D16DC4C36911F1585AF0ACE7AAFD7E7

然后像这样编辑 sshcontrol。添加密钥指纹 (keygrip) 是一次性操作;除非您添加其他密钥,否则您无需再次编辑该文件。

$GNUPGHOME/sshcontrol
1531C8084D16DC4C36911F1585AF0ACE7AAFD7E7

将 gpg-agent 和 ssh-agent 转发到远程

此文章或章节需要扩充。

原因: 设置 ForwardAgent yes(如 OpenSSH#代理转发 中所示)怎么样? (在 讨论页:GnuPG 中讨论)

可以通过将 gpg 套接字转发到远程计算机,将 gpg-agent 转发到远程计算机,如 GnuPG wiki 所述。

首先,将以下行添加到远程计算机上的 /etc/ssh/sshd_config,以启用在连接时自动删除过时的套接字。如果没有此项,则在启用代理转发的情况下连接之前,需要手动删除远程计算机上的套接字。

/etc/ssh/sshd_config
...
StreamLocalBindUnlink yes
...
注意: 您将必须 重新加载 远程计算机上的 sshd.service,以使新配置被 sshd 加载。

在客户端上,使用 RemoteForward SSH 指令将定向到远程端口的流量转发到本地主机上的端口。如 ssh_config(5) § RemoteForward 中所述,此指令的参数是远程计算机上的监听套接字路径,然后是本地主机上的目标套接字路径。您的配置应如下所示

~/.ssh/config
Host remote_name
    ...
    RemoteForward remote_agent_socket local_agent_extra_socket
    RemoteForward remote_agent_ssh_socket local_agent_ssh_socket

第一行配置 gpg-agent 转发

  • remote_agent_socket 是远程主机上 gpgconf --list-dir agent-socket 的输出。
  • local_agent_extra_socket 是本地主机上 gpgconf --list-dir agent-extra-socket 的输出。

第二行是可选的。它配置 ssh-agent 转发

  • remote_agent_ssh_socket 是远程主机上 gpgconf --list-dir agent-ssh-socket 的输出。
  • local_agent_ssh_socket 是本地主机上 gpgconf --list-dir agent-ssh-socket 的输出。
注意: 如果使用 ssh-agent 转发,远程计算机应将 SSH_AUTH_SOCK 设置为 gpgconf --list-dir agent-ssh-socket 的输出,如 #SSH 代理 中所述)。

因此,使用默认路径,它将是

    RemoteForward /run/user/1000/gnupg/S.gpg-agent /run/user/1000/gnupg/S.gpg-agent.extra
    RemoteForward /run/user/1000/gnupg/S.gpg-agent.ssh /run/user/1000/gnupg/S.gpg-agent.ssh

使用此配置,调用 ssh remote_name 应自动将 gpg-agent 转发到远程计算机,并允许将您的 gpg 密钥用于解密/签名(如果包含第二个 RemoteForward 行,则允许将 ssh-agent 与 gpg 一起使用)。

智能卡

此文章或章节需要扩充。

原因: GnuPG 2.3+ 有一个 gpg-card(1) 工具。 (在 讨论页:GnuPG 中讨论)

GnuPG 使用 scdaemon 作为您的智能卡读卡器的接口,请参阅 手册页 scdaemon(1) 了解详细信息。

GnuPG 的 gpg-card 工具可用于配置 scdaemon,并用作智能卡配置的前端,请参阅 gpg-card(1) 了解详细信息。

警告: GnuPG 2.4.3(以及 Arch Linux 未打包的 2.2.42、2.4.2)包含一个安全漏洞,如果您使用它通过 gpg --edit-card 命令将密钥移动到智能卡,则可能会保留明文私钥备份。[13] 有关信息和使用 gpg-card checkkeys 进行修复的信息,请参阅 GnuPG 建议

仅 GnuPG 设置

注意: 要允许 scdaemon 直接访问 USB 智能卡读卡器,必须安装可选依赖项 libusb-compat

如果您不打算使用其他卡,而只使用基于 GnuPG 的卡,则应检查 ~/.gnupg/scdaemon.conf 中的 reader-port 参数。值 '0' 指的是第一个可用的串行端口读卡器,值 '32768'(默认值)指的是第一个 USB 读卡器。

GnuPG 与 pcscd (PCSC Lite)

pcscd(8) 是一个守护进程,用于处理对智能卡(SCard API)的访问。在早期版本中,如果 GnuPG 的 scdaemon 无法直接连接到智能卡(例如,通过使用其集成的 CCID 支持),它会回退并尝试使用 PCSC Lite 驱动程序查找智能卡。自版本 2.4 以来,但是,您将必须在 ~/.gnupg/scdaemon.conf 中添加 disable-ccid 选项,才能使用 pcscd。

要使用 pscsd,安装 pcscliteccid。然后 启动 和/或 启用 pcscd.service。或者,启动和/或启用 pcscd.socket 以在需要时激活守护进程。

始终使用 pcscd

如果您正在使用任何带有 opensc 驱动程序的智能卡(例如:来自某些国家的身份证),您应该注意 GnuPG 配置。开箱即用,当使用 gpg --card-status 时,您可能会收到如下消息

gpg: selecting openpgp failed: ec=6.108

默认情况下,scdaemon 将尝试直接连接到设备。如果读卡器正在被另一个进程使用,则此连接将失败。例如:OpenSC 使用的 pcscd 守护进程。为了应对这种情况,我们应该使用与 opensc 相同的底层驱动程序,以便它们可以很好地协同工作。为了指示 scdaemon 使用 pcscd,您应该从 ~/.gnupg/scdaemon.conf 中删除 reader-port,指定 libpcsclite.so 库的位置,并禁用 ccid,以确保我们使用 pcscd

~/.gnupg/scdaemon.conf
pcsc-driver /usr/lib/libpcsclite.so
card-timeout 5
disable-ccid

如果您不使用 OpenSC,请检查 scdaemon(1)

与 pcscd 共享访问

GnuPG scdaemon 是唯一流行的 pcscd 客户端,它在连接到 pcscd 时使用 PCSC_SHARE_EXCLUSIVE 标志。其他客户端(如浏览器和 电子身份识别 中列出的程序使用的 OpenSC PKCS#11)正在使用 PCSC_SHARE_SHARED,它允许同时访问单个智能卡。当有其他客户端连接时,pcscd 不会给予智能卡独占访问权限。这意味着要使用 GnuPG 智能卡功能,您必须事先关闭所有打开的浏览器窗口或执行其他不方便的操作。

从版本 2.2.28 LTS 和 2.3.0 开始,您可以通过修改 scdaemon.conf 文件并在其末尾添加行 pcsc-shared 来启用共享访问。请记住,scdaemon(1) § --pcsc-shared 将此标志描述为“有点危险的选项”,因为“某些信息是从卡中缓存的”。

多应用小程序智能卡

当使用 YubiKey 或其他带有 OpenSC PKCS#11 的多应用小程序 USB 加密狗时,可能会遇到问题,其中 OpenSC 将您的 Yubikey 从 OpenPGP 切换到 PIV 小程序,从而破坏 scdaemon

您可以通过强制 OpenSC 也使用 OpenPGP 小程序来解决此问题。打开 /etc/opensc.conf 文件,搜索 Yubikey 并将 driver = "PIV-II"; 行更改为 driver = "openpgp";。如果没有这样的条目,请使用 pcsc_scan。搜索应答复位 ATR: 12 34 56 78 90 AB CD ...。然后在 app 块中创建一个新的 card_atr 块,引用您的设备 ATR。

/etc/opensc.conf
app default {
    ...
    card_atr 12:23:34:45:67:89:ab:cd:... {
        name = "YubiKey Neo";
        driver = "openpgp"
    }
}
...

之后,您可以使用 pkcs11-tool -O --login 测试 OpenPGP 小程序是否默认被选中。其他 PKCS#11 客户端(如浏览器)可能需要重新启动才能应用此更改。

在远程客户端上使用智能卡

例如,如果您通过 SSH 登录到计算机或通过 usbipd-win 将智能卡共享到 WSL,并尝试通过 pcscd 使用连接的设备,您会注意到如下错误

gpg: selecting card failed: No such device
gpg: OpenPGP card not available: No such device

这是由于 Polkit 限制了对本地客户端的访问。要修复此问题,您可以添加一个规则以允许某些用户在所有情况下都可以访问。以下规则允许 wheel 组中的所有用户通过 pcscd 访问设备

/etc/polkit-1/rules.d/99-pcscd.rules
polkit.addRule(function(action, subject) {
    if (action.id == "org.debian.pcsc-lite.access_card" &&
        subject.isInGroup("wheel")) {
        return polkit.Result.YES;
    }
});
polkit.addRule(function(action, subject) {
    if (action.id == "org.debian.pcsc-lite.access_pcsc" &&
        subject.isInGroup("wheel")) {
        return polkit.Result.YES;
    }
});

创建文件后,请确保 重新启动 polkit.service

OpenPGP 兼容性

GnuPG 最初是 OpenPGP 格式的实现。目前,该项目基于 RFC 4880,并且不支持 RFC 9580(它取代了 RFC 4880)。

但是,从 2.4.0 版本(自 2022 年 12 月起)开始,GnuPG 已选择在 IETF 流程之外推出对格式的更改和扩展(参见 draft-koch-librepgp)。

大多数 GnuPG 专有格式(与 OpenPGP 标准 不同)都带有“版本 5”(此版本未在 IETF OpenPGP 标准中使用),并引入了不兼容性

外部评论对 GnuPG 格式扩展的合理性提出了担忧(参见 LibrePGP 中已知的安全问题摘要)。

有关对 GnuPG 特定格式更改的担忧的更深入讨论,请参阅 对“对 OpenPGP 更新的评论的评论”的评论

Arch Linux 的立场是优先考虑与 OpenPGP 标准的兼容性。为此,诸如 默认情况下还原 RFC4880bis 的补丁 之类的补丁被应用于 gnupg 软件包。这确保了与其他 OpenPGP 实现的长期兼容性,并默认情况下避免了供应商锁定。

禁用不受支持的 AEAD 机制

使用 gnupg 2.4,gpg 生成密钥,这些密钥声明支持 GnuPG 特定的 AEAD 加密机制(基于 OCB)。但是,其他 OpenPGP 实现不支持这种 AEAD 风味!

尽管许多下游试图通过 修补 GnuPG 源代码 来删除此新默认值,但在使用 --full-gen-key 时,仍然为新密钥设置了基于 OCB 的自定义 AEAD 加密机制。

可以使用 gpg 本身来检查是否为密钥设置了 GnuPG 的自定义 AEAD

$ gpg --expert --edit-key <FINGERPRINT>
gpg> showpref
[ultimate] (1). Foobar McFooface (test) <foobar@mcfooface.com>
    Cipher: AES256, AES192, AES, 3DES
    AEAD: OCB
    Digest: SHA512, SHA384, SHA256, SHA224, SHA1
    Compression: ZLIB, BZIP2, ZIP, Uncompressed
    Features: MDC, AEAD, Keyserver no-modify

可以禁用此机制

gpg> setpref AES256 AES192 AES SHA512 SHA384 SHA256 SHA224 ZLIB BZIP2 ZIP
Set preference list to:
    Cipher: AES256, AES192, AES, 3DES
    AEAD:
    Digest: SHA512, SHA384, SHA256, SHA224, SHA1
    Compression: ZLIB, BZIP2, ZIP, Uncompressed
    Features: MDC, Keyserver no-modify
Really update the preferences? (y/N) y

技巧和窍门

不同的算法

您可能想要使用更强的算法

~/.gnupg/gpg.conf
...

personal-digest-preferences SHA512
cert-digest-algo SHA512
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
personal-cipher-preferences TWOFISH CAMELLIA256 AES 3DES

在最新版本的 GnuPG 中,使用的默认算法是 SHA256 和 AES,这两种算法对于大多数人来说都足够安全。但是,如果您使用的 GnuPG 版本早于 2.1,或者如果您想要更高的安全级别,那么您应该遵循上述步骤。

加密密码

加密一些密码可能很有用,这样它就不会以明文形式写入配置文件中。一个很好的例子是您的电子邮件密码。

首先创建一个包含您的密码的文件。您需要在密码后保留一个空行,否则 gpg 在评估文件时将返回错误消息。

然后运行

$ gpg -e -a -r user-id your_password_file

-e 用于加密,-a 用于 armor (ASCII 输出),-r 用于接收者用户 ID。

您将得到一个新的 your_password_file.asc 文件。

提示: pass 自动化了这个过程。

更改信任模型

默认情况下,GnuPG 使用 信任网络 作为信任模型。您可以通过在添加密钥时添加 --trust-model=tofu 或将此选项添加到您的 GnuPG 配置文件中,将其更改为 首次使用时信任。更多详细信息请参见 发送到 GnuPG 列表的这封电子邮件

隐藏所有接收者 ID

默认情况下,接收者的密钥 ID 位于加密消息中。可以在加密时使用 hidden-recipient user-id 为接收者删除此 ID。要为所有接收者删除它,请将 throw-keyids 添加到您的配置文件中。这有助于隐藏消息的接收者,并且是针对流量分析的有限对策(即,使用一点社会工程学,任何能够解密消息的人都可以检查其他接收者中是否有人是他们怀疑的人)。在接收端,它可能会减慢解密过程,因为必须尝试所有可用的密钥(例如,使用 --try-secret-key user-id)。

使用 caff 进行密钥签名聚会

为了允许用户验证密钥服务器和密钥环上的密钥(即确保它们来自他们声称的身份),PGP/GPG 使用 信任网络。密钥签名聚会允许用户在物理位置聚在一起以验证密钥。Zimmermann-Sassaman 密钥签名协议是一种使这些聚会非常有效的方式。 在此处 您将找到一篇操作指南文章。

为了更轻松地签署密钥并在密钥签名聚会后将签名发送给所有者,您可以使用工具 caff。它可以从 AUR 安装,软件包为 caff-gitAUR

要将签名发送给其所有者,您需要一个正常工作的 MTA。如果您还没有,请安装 msmtp

始终显示长 ID 和指纹

要始终显示长密钥 ID,请将 keyid-format 0xlong 添加到您的配置文件中。要始终显示密钥的完整指纹,请将 with-fingerprint 添加到您的配置文件中。

自定义功能

为了进一步自定义,还可以为您的密钥设置自定义功能。以下功能可用

  • 认证(仅适用于主密钥)- 允许密钥创建证明,证明其他密钥上的用户 ID 是正确的。
  • 签名 - 允许密钥创建数据的加密签名,其他人可以使用公钥进行验证。
  • 加密 - 允许任何人使用公钥加密数据,只有私钥可以解密。
  • 身份验证 - 允许密钥使用各种非 GnuPG 程序进行身份验证。该密钥可以用作例如 SSH 密钥。

可以通过运行以下命令来指定主密钥的功能

$ gpg --full-generate-key --expert
警告: 当使用 --full-generate-key 时,生成的密钥将声明一个 AEAD 机制,其他 OpenPGP 实现无法理解该机制。要在密钥创建后禁用此机制,请参阅 #禁用不受支持的 AEAD 机制

并选择一个允许您设置自己的功能的选项。

与此类似,要为子密钥指定自定义功能,请将 --expert 标志添加到 gpg --edit-key,有关更多信息,请参阅 #编辑您的密钥

故障排除

su

当使用 pinentry 时,您必须拥有正在使用的终端设备(例如 /dev/tty1)的适当权限。但是,使用 su(或 sudo),所有权仍然属于原始用户,而不是新用户。这意味着 pinentry 将失败并显示 Permission denied 错误,即使是以 root 用户身份。如果在尝试使用 ssh 时发生这种情况,将返回类似 sign_and_send_pubkey: signing failed: agent refused operation 的错误。解决方法是在使用 pinentry 之前(即使用带有代理的 gpg)在某个时间点更改设备的权限。如果以 root 用户身份执行 gpg,只需在使用 gpg 之前立即将所有权更改为 root

# chown root $(tty)

然后在 su(或 sudo)终止后将其改回。

注意: tty 的所有者必须与运行 pinentry 的用户匹配。仅仅是 tty 组的成员是不够的
提示: 如果您使用 script 运行 gpg,它将使用具有正确所有权的新 tty
# script -q -c "gpg --gen-key" /dev/null

代理抱怨文件结尾

如果 pinentry 程序是 /usr/bin/pinentry-gnome3,则它需要 DBus 会话总线才能正常运行。有关详细信息,请参阅 常规故障排除#会话权限

或者,您可以使用 #pinentry 中描述的各种不同选项。

KGpg 配置权限

kgpg 访问 ~/.gnupg/ 选项时出现过问题。一个问题可能是已弃用的 options 文件导致的,请参阅 bug 报告。

GNOME on Wayland 覆盖 SSH 代理套接字

对于 Wayland 会话,gnome-sessionSSH_AUTH_SOCK 设置为标准的 gnome-keyring 套接字 $XDG_RUNTIME_DIR/keyring/ssh。这会覆盖在其他地方设置的任何值。

有关如何禁用此行为,请参阅 GNOME/Keyring#禁用

mutt

Mutt 可能无法正确使用 gpg-agent,您需要在运行 mutt 时设置一个 环境变量 GPG_AGENT_INFO(内容无关紧要)。还要确保正确启用密码缓存,请参阅 #缓存密码

请参阅 此论坛帖子

“丢失”的密钥,升级到 gnupg 版本 2.1

gpg --list-keys 未能显示曾经存在的密钥,并且应用程序抱怨密钥丢失或无效时,某些密钥可能尚未迁移到新格式。

请阅读 GnuPG 无效数据包解决方法。基本上,它说明旧的 pubring.gpgsecring.gpg 文件中的密钥存在错误,这些文件现在已被新的 pubring.kbx 文件和 private-keys-v1.d/ 子目录和文件取代。您可以使用以下命令恢复丢失的密钥

$ cd
$ cp -r .gnupg gnupgOLD
$ gpg --export-ownertrust > otrust.txt
$ gpg --import .gnupg/pubring.gpg
$ gpg --import-ownertrust otrust.txt
$ gpg --list-keys

gpg 在所有密钥服务器上挂起(尝试接收密钥时)

如果 gpg 在尝试接收密钥时在某个密钥服务器上挂起,您可能需要终止 dirmngr 以访问实际上正在工作的其他密钥服务器,否则它可能会在所有密钥服务器上持续挂起。

未检测到智能卡

您的用户可能没有访问智能卡的权限,这会导致抛出 card error 错误,即使卡已正确设置并插入。

一种可能的解决方案是添加一个新的组 scard,其中包括需要访问智能卡的用户。

然后使用 udev 规则,类似于以下内容

/etc/udev/rules.d/71-gnupg-ccid.rules
ACTION=="add", SUBSYSTEM=="usb", ENV{ID_VENDOR_ID}=="1050", ENV{ID_MODEL_ID}=="0116|0111", MODE="660", GROUP="scard"

需要根据 lsusb 输出调整 VENDOR 和 MODEL,以上示例适用于 YubikeyNEO。

服务器“gpg-agent”比我们旧 (x < y)

如果 gnupg 已升级但旧的 gpg-agent 仍在运行,则会出现此警告。重启用户gpg-agent.socket(即,重启时使用 --user 标志)。

IPC 连接调用失败

确保 gpg-agentdirmngr 没有运行,可以使用 killall gpg-agent dirmngr 终止它们,并且 $GNUPGHOME/crls.d/ 文件夹的权限设置为 700

默认情况下,gnupg 软件包使用 /run/user/$UID/gnupg/ 目录作为套接字。GnuPG 文档指出这是首选目录(并非所有文件系统都支持套接字)。验证您的 agent-socket 配置是否指定了具有适当文件系统的路径。您可以通过运行 gpgconf --list-dirs agent-socket 找到 agent-socket 的路径设置。

使用 gpg-agent --daemon 测试 gpg-agent 是否成功启动。

缓解中毒的 PGP 证书

在 2019 年 6 月,一位未知攻击者用数万(或数十万)个签名(CVE-2019-13050)垃圾邮件轰炸了几个备受瞩目的 PGP 证书,并将这些签名上传到密钥服务器。密钥环中存在这些中毒的证书会导致 gpg 挂起,并显示以下消息

gpg: removing stale lockfile (created by 7055)

可能的缓解措施是按照这篇 博客文章 删除中毒的证书。

无效的 IPC 响应和设备的不适当 ioctl

默认的 pinentry 程序是 /usr/bin/pinentry-gtk-2。如果 gtk2 不可用,pinentry 将回退到 /usr/bin/pinentry-curses 并导致签名失败

gpg: signing failed: Inappropriate ioctl for device
gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device

您需要为 pinentry 程序 /usr/bin/pinentry-tty/usr/bin/pinentry-curses 设置 GPG_TTY 环境变量。

$ export GPG_TTY=$(tty)

密钥块资源不存在

如果您在尝试导入密钥时收到类似这样的错误

gpg: keyblock resource 'gnupg_home/pubring.kbx': No such file or directory

这是因为如果 GnuPG 的主目录尚不存在,则 GnuPG 不会创建它。只需手动创建它即可

$ mkdir -m 700 gnupg_home

子密钥创建时具有受限功能

在某些情况下,使用自定义功能集创建子密钥会导致子密钥标记为“受限”。当在交互式提示中切换功能时,使用选项 7 或 8(“设置您自己的功能”)的 addkey 命令中会发生这种情况。一种解决方法是在提示选择功能时,直接以字符串形式输入所需的功能集,而不是切换单个功能。例如,输入“=A”以创建一个仅具有身份验证功能的子密钥。

另请参阅