在gpg
的手册页中,有密钥 ID 的示例:
234567C4
0F34E556E
01347A56A
0xAB123456
234AABBCC34567C4
0F323456784E56EAB
01AB3FED1347A5612
0x234AABBCC34567C4
Run Code Online (Sandbox Code Playgroud)
和指纹:
1234343434343434C434343434343434
123434343434343C3434343434343734349A3434
0E12343434343434343434EAB3484343434343434
0xE12343434343434343434EAB3484343434343434
Run Code Online (Sandbox Code Playgroud)
我的直觉是,前导 0 表示八进制,前导 0x 表示十六进制,但似乎并非如此。
有哪些不同的表现形式?
注意:在我开始之前,这里的所有表示都是十六进制的。没有任何其他的代表。
手册页似乎很清楚这些值的来源。密钥 ID 是 SHA-1 指纹的一部分。
X.509 证书的密钥 ID 是其 SHA-1 指纹的低 64 位。使用密钥 ID 只是一种快捷方式,对于所有自动处理,都应使用指纹。
所有这些值是十六进制的,符号允许与前缀一个数字0x
,一个0
,或简单地用一个非零值开始。
注意:使用密钥 ID 本质上是一个坏主意,因为它们本质上是获取指纹的一部分来识别给定的密钥。问题在于在密钥 ID 之间生成冲突有点微不足道。有关此问题的更多信息,请参阅这篇文章,标题为:Short key IDs are bad news (with OpenPGP and GNU Privacy Guard)。
摘抄总结:我们(通过 GNU Privacy Guard 依赖 OpenPGP 的 Debian 社区)停止使用短密钥 ID 很重要。OpenPGP 和 GPG 中没有漏洞。但是,使用短密钥 ID(如 0x70096AD1)在根本上是不安全的;很容易为短密钥 ID 产生冲突。我们应该始终使用 64 位(或更长)的密钥 ID,例如:0x37E1C17570096AD1 或 0xEC4B033C70096AD1。
TL;DR:现在给出两个结果:
gpg --recv-key 70096AD1
而指纹:
这种格式是从字符串的长度及其内容或 0x 前缀推导出来的。请注意,只有 20 字节的版本指纹可用于 gpgsm(即证书的 SHA-1 哈希)。
使用 gpg 时,可以附加感叹号 (!) 以强制使用指定的主键或辅助键,而不是尝试计算要使用的主键或辅助键。
指定密钥 ID 的最佳方法是使用指纹。这避免了在存在重复的密钥 ID 的情况下的任何歧义。
我建议看一看维基百科页面,标题为:公钥指纹。它详细说明了指纹是如何生成的。总结如下:
摘抄
公钥(以及可选的一些附加数据)被编码为字节序列。为了确保以后可以重新创建相同的指纹,编码必须是确定性的,并且任何额外的数据都必须与公钥一起交换和存储。附加数据通常是使用公钥的任何人都应该知道的信息。附加数据的示例包括:密钥应与哪些协议版本一起使用(在 PGP 指纹的情况下);以及密钥持有者的姓名(在 X.509 信任锚指纹的情况下,附加数据由 X.509 自签名证书组成)。
上一步生成的数据使用加密哈希函数(例如 MD5 或 SHA-1)进行哈希处理。
如果需要,可以截断散列函数输出以提供更短、更方便的指纹。
此过程会生成一个短指纹,可用于验证更大的公钥。例如,典型的 RSA 公钥长度为 1024 位或更长,而典型的 MD5 或 SHA-1 指纹长度仅为 128 或 160 位。
当显示供人工检查时,指纹通常被编码为十六进制字符串。然后将这些字符串格式化为字符组以提高可读性。例如,SSH 的 128 位 MD5 指纹将显示如下:
Run Code Online (Sandbox Code Playgroud)43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8