如何使用 gpg 获取 ASCII 装甲 PGP 密钥的指纹?

jwo*_*der 5 gpg

我有一个secret.asc包含 ASCII 装甲(即纯文本并以 开头-----BEGIN PGP PRIVATE KEY BLOCK-----)PGP/GPG 秘密/私钥的文件,我想知道它的 40 个字符的密钥指纹,而无需将其导入我的 GPG 密钥环。不幸的是,我尝试过的任何命令都没有向我提供该信息。

我试过的

以下失败的尝试是在 Ubuntu Xenial 16.04.5 上运行的,gpg 版本为 1.4.20,gpg2 版本为 2.1.11。有问题的密钥仅出于实验目的而创建,不会用于任何用途,因此我不在乎输出是否透露太多信息。

$ gpg --with-fingerprint secret.asc
sec  2048R/161722B3 2018-09-12 
uid                            Testing <testing@testing.nil>
Run Code Online (Sandbox Code Playgroud)

只有短密钥ID,没有指纹。

$ gpg2 --with-fingerprint secret.asc
gpg: DBG: FIXME: merging secret key blocks is not anymore available
gpg: DBG: FIXME: No way to print secret key packets here
Run Code Online (Sandbox Code Playgroud)

错误。

$ gpg --with-fingerprint --no-default-keyring --secret-keyring ./secret.asc --list-secret-keys
gpg: [don't know]: invalid packet (ctb=2d)
gpg: keydb_search_first failed: invalid packet
Run Code Online (Sandbox Code Playgroud)

错误。

$ gpg2 --with-fingerprint --no-default-keyring --secret-keyring ./secret.asc --list-secret-keys
/home/jwodder/.gnupg/pubring.gpg
--------------------------------
...
Run Code Online (Sandbox Code Playgroud)

出于某种原因,这列出了我的密钥环中的密钥。

$ gpg --dry-run --import -vvvv secret.asc
gpg: using character set `utf-8'
gpg: armor: BEGIN PGP PRIVATE KEY BLOCK
gpg: armor header: Version: GnuPG v1
:secret key packet:
        version 4, algo 1, created 1536783228, expires 0
        skey[0]: [2048 bits]
        skey[1]: [17 bits]
        skey[2]: [2047 bits]
        skey[3]: [1024 bits]
        skey[4]: [1024 bits]
        skey[5]: [1021 bits]
        checksum: 386f
        keyid: 07C0845B161722B3
:signature packet: algo 1, keyid 07C0845B161722B3
        version 4, created 1536783228, md5len 0, sigclass 0x1f
        digest algo 2, begin of digest b6 12
        hashed subpkt 2 len 4 (sig created 2018-09-12)
        hashed subpkt 12 len 22 (revocation key: c=80 a=1 f=9F3C2033494B382BEF691BB403BB6744793721A3)
        hashed subpkt 7 len 1 (not revocable)
        subpkt 16 len 8 (issuer key ID 07C0845B161722B3)
        data: [2048 bits]
:user ID packet: "Testing <testing@testing.nil>"
:signature packet: algo 1, keyid 07C0845B161722B3
        version 4, created 1536783228, md5len 0, sigclass 0x13
        digest algo 2, begin of digest 33 ee
        hashed subpkt 2 len 4 (sig created 2018-09-12)
        hashed subpkt 27 len 1 (key flags: 03)
        hashed subpkt 9 len 4 (key expires after 32d3h46m)
        hashed subpkt 11 len 5 (pref-sym-algos: 9 8 7 3 2)
        hashed subpkt 21 len 5 (pref-hash-algos: 8 2 9 10 11)
        hashed subpkt 22 len 3 (pref-zip-algos: 2 3 1)
        hashed subpkt 30 len 1 (features: 01)
        hashed subpkt 23 len 1 (key server preferences: 80)
        subpkt 16 len 8 (issuer key ID 07C0845B161722B3)
        data: [2046 bits]
gpg: sec  2048R/161722B3 2018-09-12   Testing <testing@testing.nil>
gpg: key 161722B3: secret key imported
gpg: pub  2048R/161722B3 2018-09-12  Testing <testing@testing.nil>
gpg: writing to `/home/jwodder/.gnupg/pubring.gpg'
gpg: using PGP trust model
gpg: key 793721A3: accepted as trusted key
gpg: key 161722B3: public key "[User ID not found]" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
Run Code Online (Sandbox Code Playgroud)

唯一能找到的指纹是撤销密钥的指纹。

$ gpg2 --dry-run --import -vvvv secret.asc
Run Code Online (Sandbox Code Playgroud)

与上面相同的输出。

$ gpg --list-packets secret.asc
$ gpg2 --list-packets secret.asc
Run Code Online (Sandbox Code Playgroud)

--dry-run --import -vvvv命令的输出基本相同,只是没有gpg:行。

Kep*_*epi 10

这可能会随着 GnuPG 的新版本而改变,因为您目前可以在一个管道中执行此操作:

$ gpg --with-colons --import-options show-only --import --fingerprint < secret.asc | awk -F: '$1 == "fpr" {print $10;}'
Run Code Online (Sandbox Code Playgroud)

主要的游戏改变者是import-options启用假导入的选项。我们只是处理文件,因为它会被导入,但事实并非如此。

选项--with-colons保证了我们在上一部分中使用的稳定机器可解析的格式awk

awk只需从带有指纹的行开始打印第 10 列(以 开头fpr)。


jwo*_*der 6

正如评论中所示,最简单的解决方案似乎是首先删除密钥,然后--list-secret-keys在新文件上运行:

$ gpg --dearmor secret.asc  # Creates secret.asc.gpg
$ gpg --with-fingerprint --no-default-keyring --secret-keyring ./secret.asc.gpg --list-secret-keys
Run Code Online (Sandbox Code Playgroud)

令人烦恼的是,虽然可以使用该选项将已删除的密钥写入标准输出-o -,但既不--secret-keyring ---secret-keyring /dev/stdin不允许第二个命令从标准输入读取密钥,所以用管道将两个命令组合成一个命令不是一种选择。此外,运行第二个命令 withgpg2而不是gpg仍然无法给出所需的输出。

一种稍微更复杂的方法,但似乎适用于 的两个版本gpg,是将密钥导入到临时 GPG 主目录中,然后列出临时主目录的私钥:

$ mkdir -m 0700 tmphome
$ gpg --homedir tmphome --import secret.asc
$ gpg --homedir tmphome --with-fingerprint --list-secret-keys
Run Code Online (Sandbox Code Playgroud)