The SignedData subtype of a CADES, CMS or PKCS#7 1.5 signature has a collection of SignerInfo blocks defined here contains basically:
- SignerIdentifier: key into certificates collection
- DigestAlgorithmIdentifier: which algorithm was used to calculate message digest
- SignedAttributes (optional): the sealed data:
- SignatureAlgorithmIdentifier: which algorithm was used to calculate the signature (over SignedAttributes)
- SignatureValue: the signature value
- UnsignedAttributes (optional)
The SignedAttributes may contain, depending on the type of signature:
- ContentType: type of signed content
- MessageDigest
- SigningTime
- CounterSignature
If we would simplify this using just the first signature found and using my fork of pyx509 this could be some type of code like this one (not tested):
from pyx509.models import PKCS7
pkcs7 = PKCS7.from_der(here_goes_your_pks7_signature_data_der_encoded)
signer_info = pkcs7.content.signerInfos[0]
auth_attrs = signer_info.auth_attributes
for attr in auth_attrs.attributes:
if attr.type == '1.2.840.113549.1.9.4': # Message Digest OID
message_digest = attr.value
print "Digest: %s#%s" % (signer_info.oid2name(signer_info.digest_algorithm), messageDigest)