SignedXml.LoadXml() throws a CryptographicException

557 Views Asked by At

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

1

There are 1 best solutions below

0
On BEST ANSWER

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