SignedXml checksignature returns false

若如初见. 提交于 2019-12-03 12:15:11

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.

Had a similar issue with Saml as Timores. The Saml needed to be decoded from Base64 but first i used:

var saml = System.Text.Encoding.Default.GetString(Convert.FromBase64String(samlToken))

But this used ASCII decoding and had trouble with special characters. Which means the XML was slightly different from when it was signed and that is why it failed. Changed it to:

var saml = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(samlToken))

and it worked for all cases.

So be sure that you are using the right encoding!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!