I have a connection to an external WebService which was running flawless for ages until medio may 2018. Suddenly I started getting a CryptographicException with the message "Malformed XML Signature". My investigation tells me the following:
The exception is thrown from the line LoadXml(signature); in a class that inherits from System.Security.Cryptography.Xml.SignedXml
Here's the code:
public bool CheckAssertionSignature()
{
if (Xml == null || Xml.DocumentElement == null)
return false;
var xmlass = Xml.DocumentElement.LocalName == "Assertion" ? Xml.DocumentElement : Xml.GetElementsByTagName("Assertion", Namespaces.Saml)[0] as XmlElement;
var signature = xmlass.GetElementsByTagName("Signature", Namespaces.Ds)[0] as XmlElement;
if (signature == null) return false;
LoadXml(signature);
var cert = KeyInfo.Cast<KeyInfoX509Data>().Select(d => d.Certificates[0] as X509Certificate2).FirstOrDefault(c => c != null);
return cert != null && CheckSignature(cert, true);
}
What I've learned so far is: A colleague and I have tested the code locally on two different versions of windows 10. His version is newer than mine. He gets the error and I don't.
The xml processed by the code is identical
The error started on the 16th of may 2018 and on that date the server installed this security update https://support.microsoft.com/da-dk/help/4099635/security-and-quality-rollup-for-net-framework-3-5-4-5-2-4-6-4-6-1-4-6
We know that a similar update earlier caused a similar problem: https://support.microsoft.com/en-us/help/3148821/after-you-apply-security-update-3141780-net-framework-applications-enc
Has anyone an idea about how to solve this problem (and is anybody else experiencing the problem)?
PS. The code is running on a Windows srv 2012 R2 and the problem also exists on a windows srv 2016
We found a solution! It seems that the System.Security update has forced a more strict validation of the XML Signatures.
In the XML we receive, the Signature elements id property is written "id". According to Schema for XML Signatures (http://www.w3.org/2000/09/xmldsig#) it should be "Id". The LoadXml method before the security update did not throw up about this, but after it does.
Since the received XML is with the inappropriate attribute , we have create the following workaround to change the attribute:
if (signature.Attributes.GetNamedItem("id") is XmlAttribute oldId)
{
signature.Attributes.Remove(oldId);
if (signature.OwnerDocument != null)
{
var newId = signature.OwnerDocument.CreateAttribute("Id");
newId.Value = oldId.Value;
signature.Attributes.Append(newId);
}
}
Although we don't understand why the validation should be so strict, that only "Id" validates as ok... Never the less, I doubt we get through to Microsoft, rolling it back :D