Copy link to clipboard
Copied
Hello,
So as the title suggests, I'm trying to write Python code to validate digital signatures in PDF 1.6 files.
I read all the documentation I could find on the subject, but the truth is I can't understand how Adobe comes up with its signature.
Indeed, the signature part of the file looks like this :
397 0 obj
<</ByteRange[ 0 93895 98647 2347558] /Contents<3082......0a000000...000>/Filter .....
When I manually decode the signature in the PKCS7 data I obtain a hash :
1446...78f2
But, when I hash the following data :
%PDF-1.6.....<</ByteRange[ 0 93895 98647 2347558] /Contents/Filter....%EOF[0x0d0a]
I can't get the same hash (d2c9...02af)
Same goes for : %PDF-1.6.....<</ByteRange[ 0 93895 98647 2347558] /Contents<>/Filter....%EOF[0x0d0a] with hash 96d0...3fb2
Can somebody help me figure this out ?
When I manually decode the signature in the PKCS7 data I obtain a hash :
1446...78f2
You have to take care when analyzing a PKCS#7 signature container, it may contain multiple digests, each with a different function.
The SignerInfo object in your signature container has signed attributes (aka authenticated attributes). Thus, the hash signed by the signature bytes therein is not the hash of the document in question but the hash of the untagged set of signed attributes:
SEQUENCE (2 elem)
OBJECT IDEN
...
Copy link to clipboard
Copied
Why does you post this in the forum for Adobe Acrobat?
Copy link to clipboard
Copied
It's my first post on this forum, where should I post this ? (I thought like, because Acrobat is the PDF reader, this was relevant)
Copy link to clipboard
Copied
Yes, you can validate signatures in Adobe Acrobat or Acrobat Reader.
Copy link to clipboard
Copied
Okay cool so I'm right to post this here ? So why did you ask me why in the first place ?
Copy link to clipboard
Copied
When I manually decode the signature in the PKCS7 data I obtain a hash :
1446...78f2
You have to take care when analyzing a PKCS#7 signature container, it may contain multiple digests, each with a different function.
The SignerInfo object in your signature container has signed attributes (aka authenticated attributes). Thus, the hash signed by the signature bytes therein is not the hash of the document in question but the hash of the untagged set of signed attributes:
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.2.840.113583.1.1.8 pdfRevocationInfoArchival (Adobe Acrobat security)
SET (1 elem)
SEQUENCE (0 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.9.3 contentType (PKCS #9)
SET (1 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.7.1 data (PKCS #7)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.9.4 messageDigest (PKCS #9)
SET (1 elem)
OCTET STRING (32 byte) D2C9C1B474BEE8C586A39001CF069CF6D44A65B27ADC701E7AC97AA9D94C02AF
The hash you are looking for is the value of the messageDigest signed attribute. It is the hash you calculated for the document
But, when I hash the following data :
%PDF-1.6.....<</ByteRange[ 0 93895 98647 2347558] /Contents/Filter....%EOF[0x0d0a]
I can't get the same hash (d2c9...02af)
Copy link to clipboard
Copied
Thank you so much ! So the 1446... corresponds to the hash of some of the PKCS7 data ?
Copy link to clipboard
Copied
So the 1446... corresponds to the hash of some of the PKCS7 data ?
Yes, it's the hash of the set of the signed attributes of the SignerInfo object in the PKCS#7 signature container.
Copy link to clipboard
Copied
Okay ! But is the messageDigest in the set of signed attributes of the SignerInfo ? Otherwise, how is the hash checked for validity ? (It has to be RSA-encrypted with the private RSA key somewhere...)
Copy link to clipboard
Copied
Okay ! But is the messageDigest in the set of signed attributes of the SignerInfo ?
Yes. I have posted the signed attributes of your signature container in my previous message, and you find the messageDigest attribute among them.
how is the hash checked for validity ?
You calculate the hash of the signed byte ranges of your PDF and compare it to the signed messageDigest attribute value. And you calculate the hash of the DER representation of the set of signed attributes and verify it against your signature value (for PKCS-1 v1.5 padded RSA that means decrypting that value and comparing; for other algorithms the mechanism may be different).
Copy link to clipboard
Copied
Thank you once again !! 🙂
Copy link to clipboard
Copied
Sorry to come back on this, but can you tell me the command you used to get this output ?
Copy link to clipboard
Copied
Sorry to come back on this, but can you tell me the command you used to get this output ?
I used an ASN.1 parser. In the case at hand https://lapo.it/asn1js/