OpenPGP签名包散列数据

时间:2012-05-29 00:02:19

标签: hash openpgp

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.

我假设倒数第二行意味着只取哈希子包的字符串并用哈希算法对其进行哈希并取其前2个字节。然而,无论我做什么,我似乎无法得到它。

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

-----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,第二个签名包为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.

但签署的数据是什么?签名前的所有数据包?只是当前签名包之前的数据包?

那里的关键示例由packet 6 + packet 13 + packet 2 + packet 14 + packet 2组成。我尝试了packet 6packet 13packet 2的各种组合(从版本号到包含散列数据),但仍无法找到散列到正确值的字符串

1 个答案:

答案 0 :(得分:2)

当您生成签名数据包时,某人 总是某人 也就是说,有一些数据被签名,并且有一个公钥,而签名的关键在于它只能由具有该确切数据和相应私钥的人制作。

所以“正在签名的数据”将是那些数据blob恰好是什么。有些示例,请参见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认证哈希   用户ID认证的常量0xB4或用户的常量0xD1   属性认证,后跟四个八位字节的数字给出   用户ID或用户属性数据的长度,然后是用户ID或   用户属性数据。