OpenPGP签名数据包散列数据

5
RFC 4880描述了版本4签名数据包,标记为2。
- One-octet signature type.
- One-octet public-key algorithm.
- One-octet hash algorithm.
- Two-octet scalar octet count for following hashed subpacket data.
Note that this is the length in octets of all of the hashed
subpackets; a pointer incremented by this number will skip over
the hashed subpackets.
- Hashed subpacket data set (zero or more subpackets).
- Two-octet scalar octet count for the following unhashed subpacket
data. Note that this is the length in octets of all of the
unhashed subpackets; a pointer incremented by this number will
skip over the unhashed subpackets.
- Unhashed subpacket data set (zero or more subpackets).
- Two-octet field holding the left 16 bits of the signed hash
value.
- One or more multiprecision integers comprising the signature.

我认为倒数第二行的意思是只需取哈希子数据包的字符串并使用哈希算法对其进行哈希,并取其前两个字节。然而,无论我做什么,似乎都做不到。

我很久以前生成了这个虚假密钥。

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG v1.39

mQGiBE5B0h8RBAD533Z5bK1IpBx02QyQL0QoJE4uFRIMGDiwXuwmZzVl+R7Vlurd
GRLsCCbE6vOOh7XQVZGzLEBy9WNzZ9m+EbCfSVAYkjS6FhLws6hG6irrnS+b3JBf
gFJ8vNGF9Z7bhx+7y7NBk0IMyWkGnUkcnav73t5FQUI2faEBN4c/yAGJZwCgjcB7
3akWk9XVWvTCsiMXxpyvkukEALXsvB6cOoFEtQq9cQHjP63fBlvD94dhhMiM0cH6
hW9JotxdK+cxFGG9ZIWgoN2PWbMJka/H4W5EL6tS+YiNAR7I1Ozkt6X16GjnQUzZ
MlSpleK+KiKVN2anRaPEoOIinHrE3ZXd6QlJ/4+OJn4IVWmSEaJpFf4QNgvEu4rh
xinyBAD2RNzREOA+wpnFZ4lDt9NZXmXdxQME/l0J9XcvWhpGsxA/MATQKImy7N49
7GT/M38F+TrpBobag1O3buE99fOLyws4Tbc+sZMdHxoiGZDAIRNQS2rv475E6ktj
7vd5CYvOkA6+8sX1+hPcNlkHtHB1OFkJRsYp6k0zkyC9adjBM7QTYWJjIDxtYWtj
bUBhYWEuY29tPohGBBMRAgAGBQJOQdIfAAoJEDBSJUXPd92GRSQAoItbtbToOg7a
/hcg2sA/aBEQNwuxAKCGR69vmSoCWoBP5waPk0UsjM3BSbjMBE5B0h8QAgCUlP7A
lfO4XuKGVCs4NvyBpd0KA0m0wjndOHRNSIz44x24vLfTO0GrueWjPMqRRLHO8zLJ
S/BXO/BHo6ypjN87Af0VPV1hcq20MEW2iujh3hBwthNwBWhtKdPXOndJGZaB7lsh
LJuWv9z6WyDNXj/SBEiV1gnPm0ELeg8Syhy5pCjMAf9QHehP2eCFqfEwTAnaOlA6
CU+rYHKPZaI9NUwCA7qD2d93/l08/+ZtFvejZW1RWrJ8qfLDRtlPgRzigoF/CXbR
iEYEGBECAAYFAk5B0h8ACgkQMFIlRc933YZRrACfUnWTjHHN+QsEEoJrwRvFmvzj
bR4An24pTpeeN+I6R59O/sdmYsAhjULX
=sStS
-----END PGP PUBLIC KEY BLOCK-----

我认为我应该做什么:

sha1("\x05\x02\x4e\x41\xd2\x1f") = "52f07613cfd61c80d2343566a8f3f487a0975b80"

\x05 - length of subpacket
\x02 - subpacket type
\x4e\x41\d2\x1f - creation time

pgpdump.net 网站上看到第一个签名数据包的哈希值(SHA 1)左侧2个字节为45 24,第二个签名数据包的哈希值左侧2个字节为 51 ac。我得到的是52 f0。很明显,我没有包含所有信息,但是缺了什么?哈希子数据包是相同的,并且在哈希数据之前的所有数据也都一样,只是它们是不同类型的签名数据包(0x13 / 0x18)。即使我添加/删除数据包字符,我仍然无法获得正确的哈希值。生成的密钥与此处显示的密钥完全相同,除了哈希值。

我应该哈希哪些数据?

编辑:稍后发现如下信息:

The concatenation of the data being signed and the signature data
from the version number through the hashed subpacket data (inclusive)
is hashed. The resulting hash value is what is signed. The left 16
bits of the hash are included in the Signature packet to provide a
quick test to reject some invalid signatures.

但是被签名的数据是什么?所有在签名之前的数据包?还是只有当前签名数据包之前的数据包?
上面的示例密钥由“数据包6 + 数据包13 + 数据包2 + 数据包14 + 数据包2”组成。我尝试了各种各样的组合,包括数据包6、数据包13和数据包2(从版本号到哈希数据),但仍然找不到正确散列值的字符串。
1个回答

2
当您生成签名数据包时,它总是由某人对某个东西进行签名。也就是说,有一些数据块被签名,以及一个公钥,签名的目的是只有拥有该确切数据和相应私钥的人才能制作出来。
“被签名的数据”将是该数据块所包含的任何内容。请参阅RFC4880第5.2.1节中的一些示例。在本例中,您可能对公钥块内的签名数据包感兴趣。
第一个是“用户ID和公钥数据包的正面认证(0x13)”。这在RFC4880的第5.2.4节中有描述。
第二个是“子密钥绑定签名”,其中主密钥(DSA密钥)保证子密钥(ElGamal仅加密)属于它。这种工作方式也在RFC4880的第5.2.4节中有描述。
下面是来自5.2.4的相关文本:
引用: 当对密钥进行签名时,哈希数据以0x99为开头,后跟密钥的两个字节长度,然后是密钥数据包的主体。(请注意,这是旧版密钥数据包的数据包头,长度为两个字节。)子密钥绑定签名(类型0x18)或主密钥绑定签名(类型0x19)然后使用与主密钥相同的格式对子密钥进行哈希(同样使用0x99作为第一个字节)。密钥吊销签名(类型0x20和0x28)仅对被吊销的密钥进行哈希。
然后是:
引用: 认证签名(类型0x10到0x13)在上述数据之后将绑定到密钥的用户ID哈希到哈希上下文中。 V3认证哈希用户ID或属性数据包的内容,不包括任何标头。 V4认证将常量0xB4哈希为用户ID认证或常量0xD1哈希为用户属性认证,后跟四个字节的数字,表示用户ID或用户属性数据的长度,然后是用户ID或用户属性数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接