I have CMS(PKCS#7 based) signature as input and I want to create equivalent xmldsig out of it. I can extract X509 certificate out of CMS message, but I don't see the way how to extract signature hash (to reuse in xmldsig field). Is there way to extract signature hash out of CMS message?
1 Answers
I have CMS(PKCS#7 based) signature as input and I want to create equivalent xmldsig out of it.
You can't convert a CMS SignedData to an XmlDSig SignedXml, they aren't signing the same thing.
CMS SignedData signs either the raw data (when no signed attributes are present) or the signed attributes (which, when present must contain the correct hash of the raw data as an attribute).
XmlDSig SignedXml uses a signature over the canonicalized SignedInfo element. The SignedInfo element contains the hash (digest) of the original data as part of its payload.
If you have the private key and understand that you need to resign after building the SignedInfo value manually, then we do get to the last part of your question:
Is there way to extract signature hash out of CMS message?
I'm not sure what "signature hash" means. If you mean "the hash of the original data", then in SignedCms that'd be something like
byte[] digest = cms.SignerInfos[0].SignedAttributes.OfType<CryptographicAttributeObject>().
FirstOrDefault(cao => cao.Oid.Value == "1.2.840.113549.1.9.4")?.Values.
OfType<Pkcs9MessageDigest>().FirstOrDefault()?.MessageDigest;
if (digest == null)
{
// Older form document, have to hash the original data again.
throw new NotImplementedException();
}
Perhaps with fewer calls to Linq extension methods and/or more assertions on correctness once the correct OID is found.

- 30,352
- 2
- 71
- 111