解析 GnuPG 密钥列表

Parsing the GnuPG secret key list

您可以通过以下操作在 GnuPG 中获取可解析的密钥列表:

gpg2 --list-secret-keys --with-colons

这里描述了输出的格式:http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS

我想编写一个 bash 函数来告诉我是否拥有有效的加密密钥和签名密钥。基于以上URL,我得出的结论是:

has_valid_secret_keys() {
  return "$(gpg2 --list-secret-keys --with-colons 2>/dev/null | \
            awk -F: 'BEGIN { sign = 0; encrypt = 0; }
                     ( ~ "sec|ssb") && ( ~ "[mfu]") {
                       if ( ~ "s") sign++
                       if ( ~ "e") encrypt++
                     }           
                     END { print !(sign * encrypt) }')"
}

也就是说,Awk 脚本匹配具有边缘、完全或最终有效性(字段 2)的秘密密钥和秘密子密钥(字段 1),然后它根据匹配记录的能力维护签名和加密密钥的计数器(字段 12)。如果这两个计数器都为零,那么我们就没有签名或加密密钥,否则我们就有了我们想要的。

这在 GnuPG 2.1 中运行良好,但当我在 GnuPG 2.0 中尝试时,--list-secret-keys 的输出中似乎没有设置 capability 字段。找到输出的文档是一项艰巨的工作;我想它一定在 v2 和 v2.1 之间发生了变化。

是否有与 GnuPG 版本无关的方法(如果可能,甚至包括 GnuPG 1.4)?


编辑感谢 Jens Erat 的回答,我更新的(即工作!)bash 函数如下:

has_valid_secret_keys() {
  # Check that both valid signing and encryption (sub)keys exist

  # Format described at http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS
  # First we find the Key IDs of secret keys and subkeys, then we
  # reference these against the public keys to check their capabilities
  return "$(gpg --list-secret-keys --with-colons 2>/dev/null | \
            awk -F: '( ~ "sec|ssb") { print  }' | \
            xargs gpg --list-keys --with-colons 2>/dev/null | \
            awk -F: 'BEGIN { sign = 0; encrypt = 0; }
                     ( ~ "[ps]ub") && ( ~ "[mfu]") {
                       if ( ~ "s") sign++
                       if ( ~ "e") encrypt++
                     }
                     END { print !(sign * encrypt) }')"
}

文档受源代码控制

您为 GnuPG 2.1is under source control, you can either look at the file's history or just fetch the GnuPG 1.4/GnuPG 2.0 个分支版本链接的文档副本。

冒号输出已经有一段时间没有改变了(它是与 GnuPG 二进制文件接口的 "API" 最相关的部分)。 capability 字段应该 return 你期望的(至少)GnuPG 1.4.

GnuPG 2.1 合并了密钥环

版本差异的问题是另一个问题(事实上,GnuPG 2.1 的行为在这里发生了变化):虽然 GnuPG 1.4 和 2.0 有一个单独的密钥存储,但它被合并到 public 密钥中GnuPG 2.1 的商店。通过此更改,一些输出发生了变化。 GnuPG 1.4 和 2.0 仅在查询 public 密钥环时列出功能; GnuPG 2.1 在列出 public 和秘密密钥时查询相同的密钥环,并且在两个命令的输出中具有相同的信息。

如果您需要支持 GnuPG 1.4 和 2.0,则必须

  1. 查询密钥然后
  2. 使用 public 键列表的输出进行过滤。