I digitally sign XML files, but need the signature tags contain the namespace prefix "ds". I researched quite the google and found many of the same questions, but no satisfactory answer.
I tried to put the "ds" manually in the file, but the signature becomes invalid. The tag "SignatureValue" signs the tag "SignedInfo" so the signature becomes invalid.
Could somebody show me how I generate the value of the tag "SignatureValue" so I can replace the signature after adding the prefix "ds"?
Apparently a lot of people ran into the same problem. After investigating source code of the class Signature, I came to conclusion that Microsoft aimed to help us. There is hardcoded prefix "ds" in the method LoadXml(). So, it is possible to generate signature, then add namespace prefix "ds" to it, load modified signature back and recompute "SignatureValue". Unfortunatelly bug in the library makes things a bit harder than they need to be. The code with workaround and comments is below.
Since you are the one signing the documents, this should be easy enough to do, but the classes in System.Security.Cryptography.Xml don't really support this.
If you only need the Signature elements to be prefixed, then, provided the Signature is not referenced in itself (or if it is part of a referenced element then so long as it's removed with a transform as in "http://www.w3.org/2000/09/xmldsig#enveloped-signature") then all you need to do is recalculate the SignatureValue based on your altered SignedInfo element. See the SignEnveloped method below for an example.
However, your signature won't pass the validation outlined in MSDN's How to: Verify the Digital Signatures of XML Documents, because rather than calculating the SignatureValue to check against by actually reading the document's SignedInfo, the SignedXml class seems to generate a new one without prefixed elements. The class below works around SignedXmls seemingly errant implementations, but there could also be validation issues in other frameworks not expecting prefixed elements.
Edit: You can see an algorithm which this post kind of alluded to in my other answer.
Assuming that it isn't possible without writing your own algorithm to canonicalize and sign the document, a possible workaround could be to "inject" the namespace prefix on the signature elements after signing, and then removing it from them before verifying.
For example: