SignedXml checksignature returns false

I dealt with signed XML's a lot in the past. All I can say is that it was a nightmare. Basically, when you sign XML, it goes through a process called canonicalization (C14N). It needs to turn XML text to a byte stream which can be signed. Whitespace & namespace handling, among others, in XML C14N standards are hard to understand, even harder to implement right. There are even multiple types of C14N.

The .NET implementation is very selective about what it accepts. It's quite possible that your other implementation doesn't work in the exact same way as the .NET one. This is very sad indeed. If you can eliminate whitespace and namespaces from your source XML before signing, for example, that could help. Also if you could make sure that both implementations use the same C14N settings.

Otherwise a lot of debugging awaits you. You could debug into the framework, or call its internal methods by hand with reflection, to see how it calculates the XML fragment and the signature. And do the same with the other implementation. Basically you need to see the exact byte streams that are signed in both cases. This is the final step of the conversion before signing. If those byte streams match, then you'll have no problems with the RSA signing part in my experience. If those don't match, as is in your case, at least you'll see where the problem is.


I just had a similar issue and lost a lot of time, maybe this can help someone.

My environment is 100% .Net 4.5, and my code uses only the SignedXml class. But a SAML assertion was accepted at one place and refused at another one.

Turned out that one place was loading the assertion through an XmlDocument instance initialized with PreserveWhitespace = true, while the other one was not.

And the assertion had been pretty-printed, so it had carriage returns and a lot of indentation spaces. Removing all carriage returns and the indentation spaces fixed my issue.