SignedXml.LoadXml() 抛出 CryptographicException
SignedXml.LoadXml() throws a CryptographicException
我有一个外部 Web 服务的连接,该连接在 2018 年 5 月之前一直 运行 完美无缺。突然我开始收到带有消息 "Malformed XML Signature" 的 CryptographicException。我的调查告诉我以下内容:
从 LoadXml(signature) 行抛出异常;在继承自 System.Security.Cryptography.Xml.SignedXml
的 class 中
代码如下:
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);
}
到目前为止我学到的是:
我和一个同事在 windows10 的两个不同版本上在本地测试了代码。他的版本比我的新。他得到了错误,而我没有。
代码处理的xml完全相同
错误始于 2018 年 5 月 16 日,服务器在该日期安装了此安全更新 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
我们知道之前的类似更新导致了类似的问题:
https://support.microsoft.com/en-us/help/3148821/after-you-apply-security-update-3141780-net-framework-applications-enc
有没有人知道如何解决这个问题(还有其他人遇到这个问题)?
PS。代码在 Windows srv 2012 R2 上 运行 并且问题也存在于 windows srv 2016
我们找到了解决办法! System.Security 更新似乎强制对 XML 签名进行了更严格的验证。
在我们收到的XML中,签名元素id属性被写成"id"。根据 XML 签名 (http://www.w3.org/2000/09/xmldsig#) 的架构,它应该是 "Id"。安全更新前的 LoadXml 方法没有抛出这个问题,但在安全更新之后。
由于收到的 XML 具有不合适的属性,我们创建了以下解决方法来更改属性:
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);
}
}
虽然我们不明白为什么验证应该如此严格,但只有 "Id" 验证为 ok... 尽管如此,我怀疑我们能否联系到 Microsoft,将其回滚 :D
我有一个外部 Web 服务的连接,该连接在 2018 年 5 月之前一直 运行 完美无缺。突然我开始收到带有消息 "Malformed XML Signature" 的 CryptographicException。我的调查告诉我以下内容:
从 LoadXml(signature) 行抛出异常;在继承自 System.Security.Cryptography.Xml.SignedXml
的 class 中代码如下:
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);
}
到目前为止我学到的是: 我和一个同事在 windows10 的两个不同版本上在本地测试了代码。他的版本比我的新。他得到了错误,而我没有。
代码处理的xml完全相同
错误始于 2018 年 5 月 16 日,服务器在该日期安装了此安全更新 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
我们知道之前的类似更新导致了类似的问题: https://support.microsoft.com/en-us/help/3148821/after-you-apply-security-update-3141780-net-framework-applications-enc
有没有人知道如何解决这个问题(还有其他人遇到这个问题)?
PS。代码在 Windows srv 2012 R2 上 运行 并且问题也存在于 windows srv 2016
我们找到了解决办法! System.Security 更新似乎强制对 XML 签名进行了更严格的验证。
在我们收到的XML中,签名元素id属性被写成"id"。根据 XML 签名 (http://www.w3.org/2000/09/xmldsig#) 的架构,它应该是 "Id"。安全更新前的 LoadXml 方法没有抛出这个问题,但在安全更新之后。
由于收到的 XML 具有不合适的属性,我们创建了以下解决方法来更改属性:
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);
}
}
虽然我们不明白为什么验证应该如此严格,但只有 "Id" 验证为 ok... 尽管如此,我怀疑我们能否联系到 Microsoft,将其回滚 :D