Creating signatures with SignedXML following ebXML standard
Hi all,
The other day a customer of mine was trying to generate XML signatures following the ebXML standard with .NET and its SignedXML class. The main issue was that they didn't know how to refer in the signature the reference to an attachment that appears in the manifest of the SOAP Envelope body here:
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<SOAP:Envelope xmlns:SOAP="https://schemas.xmlsoap..org/soap/envelope/" xmlns:eb="https://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd" xmlns:xlink="https://www.w3.org/1999/xlink" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://schemas.xmlsoap.org/soap/envelope/ https://www.oasis-open.org/committees/ebxml-msg/schema/envelope.xsd https://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd https://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd">
<SOAP:Header xsi:schemaLocation="https://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd https://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd">
...
</SOAP:Header>
<SOAP:Body>
<eb:Manifest eb:version="2.0">
<eb:Reference xlink:href="cid:ref1" />
</eb:Manifest>
</SOAP:Body>
</SOAP:Envelope>
The resultant signature didn't contain a reference like this in its SignedInfo node, so a third-party was refusing the signature:
<Reference URI="cid:ref1">
<DigestMethod Algorithm="https://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
<DigestValue>3pkh0c4HZp81qc062h/cAiZE+wM=</DigestValue>
</Reference>
Well, this is a known limitation of SignedXml when working with ebXml: SignedXml won’t support URIs with “cid:” prefix by design. SignedXml only knows how to deal with URL's as it uses XmlSecureResolver which only deals with URL's as well.
At the end, my customer managed to generate a valid ebXML signature, using SignedXml to create the Signature element and then adding the Reference element with URI=cid:ref1 "manually" into the signature element. The DigestValue of this element should be easy to generate with SHA1CryptoServiceProvider and then converted to a base64 string. Then SignedData should be re-generated to take the changes to Signature element into account.
In any case, please note that we already commented that this scenario is not supported at all by SignedXML: Which standards does SignedXml support?
Also note that people found ways to verify signatures with "cid:" prefixes, as commented here:
XML Digital Signature Verification with Unknown URI Schemes
Validating XML Digital Signatures with References Using Unrecognized URI Prefixes
I hope this helps.
Regards,
Alex (Alejandro Campos Magencio)