Over a million developers have joined DZone.

Xml Digital Signature: Signing the KeyInfo

· Agile Zone

Learn more about how DevOps teams must adopt a more agile development process, working in parallel instead of waiting on other teams to finish their components or for resources to become available, brought to you in partnership with CA Technologies.

Frederic Vidal had shown me recently a nice trick with Xml digital signatures. Suppose you want to add a signature which looks like this:

<ds:Signature xmlns:ds='http://www.w3.org/2000/09/xmldsig#' Id='Signature001'>
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315' />
<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1' />
<ds:Reference URI=''>
<ds:Transforms>
<ds:Transform Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature' />
</ds:Transforms>
<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1' />
<ds:DigestValue>sXe2PnaG...</ds:DigestValue>
</ds:Reference>
<ds:Reference URI='#KeyInfo001'>
<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1' />
<ds:DigestValue>ZOS23PQ9TcDu+G...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>jTLX0/8XkY2aCte7...</ds:SignatureValue>
<ds:KeyInfo Id='KeyInfo001'>
<ds:X509Data>
<ds:X509Certificate>E3wdSY4n7MgUmJzMIGfMA0...</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>

The interesting part is the second reference (in bold) – the signature signs the KeyInfo (#KeyInfo001), which is part of the signature element itself. The regular api to add reference to a signature is this:

var reference = new Reference();
reference.Uri = "#KeyInfo001";
However it will not work here since it will look for an element with this ID in the signed document (e.g. soap envelope). However the ID is inside the signature element itself, which is still not a part of the document because it was not create yet.
Frederic had found a nice trick: Inherit from SignedXml and override the default logic to find the references such that it will search in the signature itself (which is the base class).
public class CustomIdSignedXml : SignedXml
{
public CustomIdSignedXml(XmlDocument doc) : base(doc)
{
return;
}

public override XmlElement GetIdElement(XmlDocument doc, string id)
{
if (String.Compare(id, this.KeyInfo.Id, StringComparison.OrdinalIgnoreCase) == 0)
return this.KeyInfo.GetXml();
else
return base.GetIdElement(doc, id);
}
}
This is applicable to web services, since many soap stacks will not allow to customize them to sign the KeyInfo, and if this is required you would need to sign the message like this yourself.

Discover the warning signs of DevOps Dysfunction and learn how to get back on the right track, brought to you in partnership with CA Technologies.

Topics:

Published at DZone with permission of Yaron Naveh, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}