views:

811

answers:

2

Is there a way to set the prefix on the Signature of a Signed XML Document (SignedXml class in .Net)?

So instead of:

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#&gt;
...
</Signature>

I could have the following:

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#&gt;
...
</ds:Signature>
A: 

First of all, there really isn't any good reason to do this. The two forms are functionally equivalent. Any well-behaved XML processor will handle them absolutely identically. So unless you are trying to talk to an application that doesn't properly implement XML namespaces, it's better (IMO) just to leave the default form alone. (And even in that case, it would be better, if at all possible, to get the faulty application fixed instead.)

That said, you can manually set the prefix on the XmlElement that is returned by SignedXml.GetXml() and its child elements using XPath like this:

XmlElement signature = signedXml.GetXml();
foreach (XmlNode node in signature.SelectNodes(
    "descendant-or-self::*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#']"))
{
    node.Prefix = "ds";
}
Eric Rosenberger
I agree that it is the same, and that it should work. However, I'm not sure if I'm going to be able to get the other party to work w/it not having the ds prefix.Won't the simple act of changing the prefix after sig in generated cause it to fail validation?
mjmcinto
It could break the signature, depending on whether or not the Signature element was included in the information being signed (if the Transform doesn't exclude it, it will break). So this wouldn't work in all possible cases.
Eric Rosenberger
If you look at the SignedXml class in Reflector, it seems to be pretty much hardwired to NOT use a prefix, so unless you can get it to exclude the Signature element from the signature I'm not sure there's any other workable options...
Eric Rosenberger
Thanks. Where do you get Reflector?
mjmcinto
http://www.red-gate.com/products/reflector. Free and absolutely invaluable.
Eric Rosenberger
A: 

It can't be done. If you modify the XML after it has been signed it may not be able to be verified, which was the case in the example above. IMO this is a flaw in MSFT's digital signature implementation that you will have to live with.

A lot of people will say that there is no reason to do this, and they are technically correct. But when you are dealing with a huge vendor (i.e. a state government or bank), good luck getting them to change it on their end. Most reference implementations include it.