Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenPGP Signature Packet hashed data

Tags:

hash

openpgp

RFC 4880 describes the version 4 signature packet, tag 2, as

- 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.

and i assume that the second to last line means just take the string of the hashed subpacket and hash it with the hash algorithm and take its first 2 bytes. however, no matter what i do, i cannot seem to get it.

I generated this fake key a long time ago

-----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-----

what i think im supposed to do:

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

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

From pgpdump.net, i see that the left 2 bytes of the hash (SHA 1) value is 45 24 for the first signature packet and 51 ac for the second one. i am getting 52 f0 for both. obviously, im not including some information, but what is it? the hashed subpackets are identical, and all of the data before the hashed data are the same as well except they are different types of signature packets (0x13 / 0x18). i have been unable to get either of the correct hash values even when i add/take characters from the data packet. the key im generating is exactly the same as the key shown here except for the hash values.

what is the data that i should be hashing??

edit: if found this a little later on:

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.

but what is the data being signed? all packets before the signature? just the packet before the current signature packet?

the key example up there is made up of packet 6 + packet 13 + packet 2 + packet 14 + packet 2. i have tried all sorts of combinations of packet 6, packet 13, and packet 2 (from version number to hashed data inclusive), but still cannot find the string that hashes to the correct values

like image 915
calccrypto Avatar asked Nov 04 '22 23:11

calccrypto


1 Answers

When you generate a signature packet, it's always a signature of something by someone. That is, there's some blob of data being signed, and a public key, and the point of a signature is that it's something that's only supposed to be able to be made by someone who has that exact data and the corresponding private key.

So "the data being signed" will be whatever that blob of data happens to be. See section 5.2.1 of RFC4880 for some examples. In the present case, presumably you're interested in the signature packets inside your public key block.

The first one is a "Positive certification of a User ID and Public Key packet(0x13)". This is described in section 5.2.4 of RFC4880.

The second one is a "subkey binding signature", whereby the primary key (the DSA one) guarantees that the subkey (ElGamal encrypt-only) belongs to it. The way this works is also described in section 5.2.4 of RFC4880.

Here's the relevant text from 5.2.4:

When a signature is made over a key, the hash data starts with the octet 0x99, followed by a two-octet length of the key, and then body of the key packet. (Note that this is an old-style packet header for a key packet with two-octet length.) A subkey binding signature (type 0x18) or primary key binding signature (type 0x19) then hashes the subkey using the same format as the main key (also using 0x99 as the first octet). Key revocation signatures (types 0x20 and 0x28) hash only the key being revoked.

and then

A certification signature (type 0x10 through 0x13) hashes the User ID being bound to the key into the hash context after the above data. A V3 certification hashes the contents of the User ID or attribute packet packet, without any header. A V4 certification hashes the constant 0xB4 for User ID certifications or the constant 0xD1 for User Attribute certifications, followed by a four-octet number giving the length of the User ID or User Attribute data, and then the User ID or User Attribute data.

like image 76
Gareth McCaughan Avatar answered Nov 17 '22 20:11

Gareth McCaughan