使用GnuPG的额外解密子密钥(ADSK)。#

`额外解密子密钥(ADSK)<https://gnupg.org/blog/20230321-adsk.html>`__在用GnuPG加密信息时,可用于自动添加收件人。典型的使用情况包括

  • 一个组有一个单一的加密密钥,而不需要在组内成员之间共享私人密钥、

  • 将备份密钥添加到加密密钥中,以及

  • 设置一个主钥匙,可以为其他钥匙解密信息。

注解

要配置 ADSK,你需要 GnuPG 2.4.1 或更新版本。要用ADSK为一个密钥加密信息,你需要GnuPG 2.2.42或更新版本。

概述#

本指南解释了如何将一个备份钥匙(用户ID``backup@example.com``)作为ADSK添加到一个主钥匙(用户ID``main@example.com``)。两把钥匙都存储在一个Nitrokey上。同样的步骤可以用来为一把钥匙添加多个ADSK,或将同一把钥匙作为ADSK添加到其他多个钥匙上。

准备钥匙#

按照这些指南之一来生成这两个钥匙:

确保你能用``gpg –list-keys``列出两个键,例如::

$ gpg --list-keys main@example.com backup@example.com
pub   ed25519 2023-07-04 [SC]
      55BC284C1D30D97638DA4A2C7963A4CD00C947CE
uid           [ultimate] Main Key <main@example.com>
sub   ed25519 2023-07-04 [A]
sub   cv25519 2023-07-04 [E]

pub   ed25519 2023-07-04 [SC]
      5271152B531F7FFD8787818251FB75800E281241
uid           [ultimate] Backup Key <backup@example.com>
sub   ed25519 2023-07-04 [A]
sub   cv25519 2023-07-04 [E]

添加一个ADSK#

首先确定备份钥匙的加密子钥匙的指纹::

$ gpg --list-keys --with-subkey-fingerprints backup@example.com
pub   ed25519 2023-07-04 [SC]
      5271152B531F7FFD8787818251FB75800E281241
uid           [ultimate] Backup Key <backup@example.com>
sub   ed25519 2023-07-04 [A]
      7AEA1A0EC7BD66FF03AFEFAC8F243D8EC7678FCC
sub   cv25519 2023-07-04 [E]
      C1735CB29890EEDEABCF1D0DC9310F81D77519BC

寻找以``sub``开头的一行,其中包含字母``E``,表示一个具有加密能力的子键。这个子键的指纹被列在下一行。在这个例子中,指纹是``C1735CB29890EEDEABCF1D0DC9310F81D77519BC``。

然后确定主键的指纹::

$ gpg --list-keys main@example.com
pub   ed25519 2023-07-04 [SC]
      55BC284C1D30D97638DA4A2C7963A4CD00C947CE
uid           [ultimate] Main Key <main@example.com>
sub   ed25519 2023-07-04 [A]
sub   cv25519 2023-07-04 [E]

你可以在``pub``之后的下一行找到它,在这里是``55BC284C1D30D97638DA4A2C7963A4CD00C947CE``。

现在你可以使用``–quick-add-adsk``标志添加ADSK::

$ gpg --quick-add-adsk \
      55BC284C1D30D97638DA4A2C7963A4CD00C947CE \
      C1735CB29890EEDEABCF1D0DC9310F81D77519BC

第一个参数是主密钥的指纹。第二个参数是备份钥匙的加密子钥匙的指纹。

你可以检查ADSK是否已经被创建::

$ gpg --list-keys --with-subkey-fingerprints main@example.com
pub   ed25519 2023-07-04 [SC]
      55BC284C1D30D97638DA4A2C7963A4CD00C947CE
uid           [ultimate] Main Key <main@example.com>
sub   ed25519 2023-07-04 [A]
      9DF42A789DA4E848295C529634E35A6897DFABFD
sub   cv25519 2023-07-04 [E]
      1DFD6EA8D8B88BEA063ADB4BD75708BAF0CD49C8
sub   cv25519 2023-07-04 [R]
      C1735CB29890EEDEABCF1D0DC9310F81D77519BC

具有``R``(限制)能力的子键是ADSK。它的指纹与备份钥匙的加密子钥匙相同。

现在你可以用ADSK分发公钥。

使用ADSK#

当为主密钥加密信息时,备份密钥现在被自动添加为接收者。这方面的唯一要求是:

  • 信息的发送者有一个最新的公钥,其中包括ADSK。

  • 信息的发件人使用GnuPG 2.2.42或更新版本。

如果你添加``–verbose``标志,你可以检查信息被加密的密钥::

$ echo message | gpg --verbose --encrypt --armor --recipient main@example.com > /tmp/msg.asc
gpg: using pgp trust model
gpg: using subkey D75708BAF0CD49C8 instead of primary key 7963A4CD00C947CE
gpg: automatically retrieved 'main@example.com' via Local
gpg: This key belongs to us
gpg: reading from '[stdin]'
gpg: writing to stdout
gpg: ECDH/AES256 encrypted for: "D75708BAF0CD49C8 Main Key <main@example.com>"
gpg: ECDH/AES256 encrypted for: "C9310F81D77519BC Main Key <main@example.com>"

你也可以使用``–list-packets``选项来检查加密的信息::

$ gpg --pinentry-mode cancel --list-packets /tmp/msg.asc | grep "pubkey enc packet"
:pubkey enc packet: version 3, algo 18, keyid D75708BAF0CD49C8
:pubkey enc packet: version 3, algo 18, keyid C9310F81D77519BC

每一行``pubkey enc packet``代表一个可以解密信息的钥匙。

撤销ADSK#

如果你撤销了一个ADSK,在加密信息时,它将不再被添加为收件人。要执行撤销,用``gpg –edit-key``:打开密钥:

$ gpg --edit-key main@example.com

sec  ed25519/7963A4CD00C947CE
     created: 2023-07-04  expires: never       usage: SC
     card-no: FFFE 5E0E868D
     trust: ultimate      validity: ultimate
ssb  ed25519/34E35A6897DFABFD
     created: 2023-07-04  expires: never       usage: A
     card-no: FFFE 5E0E868D
ssb  cv25519/D75708BAF0CD49C8
     created: 2023-07-04  expires: never       usage: E
     card-no: FFFE 5E0E868D
ssb  cv25519/C9310F81D77519BC
     created: 2023-07-04  expires: never       usage: R
[ultimate] (1). Main Key <main@example.com>

用``key N``选择要撤销的子键。所选的子键被标记为星号::

gpg> key 2

sec  ed25519/7963A4CD00C947CE
     created: 2023-07-04  expires: never       usage: SC
     card-no: FFFE 5E0E868D
     trust: ultimate      validity: ultimate
ssb  ed25519/34E35A6897DFABFD
     created: 2023-07-04  expires: never       usage: A
     card-no: FFFE 5E0E868D
ssb  cv25519/D75708BAF0CD49C8
     created: 2023-07-04  expires: never       usage: E
     card-no: FFFE 5E0E868D
ssb* cv25519/C9310F81D77519BC
     created: 2023-07-04  expires: never       usage: R
[ultimate] (1). Main Key <main@example.com>

用``revkey``撤销子键,然后用``save``保存更改::

gpg> revkey
Do you really want to revoke this subkey? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
Your decision? 0
Enter an optional description; end it with an empty line:
>
Reason for revocation: No reason specified
(No description given)
Is this okay? (y/N) y


sec  ed25519/7963A4CD00C947CE
     created: 2023-07-04  expires: never       usage: SC
     card-no: FFFE 5E0E868D
     trust: ultimate      validity: ultimate
ssb  ed25519/34E35A6897DFABFD
     created: 2023-07-04  expires: never       usage: A
     card-no: FFFE 5E0E868D
ssb  cv25519/D75708BAF0CD49C8
     created: 2023-07-04  expires: never       usage: E
     card-no: FFFE 5E0E868D
ssb  cv25519/C9310F81D77519BC
     created: 2023-07-04  revoked: 2023-07-04  usage: R
[ultimate] (1). Main Key <main@example.com>

gpg> save

现在分发更新后的公钥。

注解

撤销只有在发件人用撤销的ADSK更新公钥后才会生效。已经被加密的信息仍然可以用ADSK进行解密,即使它被撤销了。