Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SignedXml.CheckSignature在.NET 4中失败,但在.NET 3.5、3或2中有效_C#_Security_Certificate_Signature_Signedxml - Fatal编程技术网

C# SignedXml.CheckSignature在.NET 4中失败,但在.NET 3.5、3或2中有效

C# SignedXml.CheckSignature在.NET 4中失败,但在.NET 3.5、3或2中有效,c#,security,certificate,signature,signedxml,C#,Security,Certificate,Signature,Signedxml,我收到了第三方网络服务的回复。我加载带有该响应的XmlDocument string txt = readStream.ReadToEnd(); response = new XmlDocument(); response.PreserveWhitespace = true; response.LoadXml(txt); return response; 现在我想验证响应是否使用证书签名。我有一个VerifyXmlDoc(xmldocumentxmldoc)方法,我在

我收到了第三方网络服务的回复。我加载带有该响应的XmlDocument

  string txt = readStream.ReadToEnd();
  response = new XmlDocument();
  response.PreserveWhitespace = true;
  response.LoadXml(txt);   
  return response;
现在我想验证响应是否使用证书签名。我有一个
VerifyXmlDoc(xmldocumentxmldoc)
方法,我在上找到了这个方法

我知道这个消息是正确的

    public bool VerifyXmlDoc(XmlDocument xmlDoc)
    {

        SignedXml signed = new SignedXml(xmlDoc);

        XmlNodeList signatureNodeList = xmlDoc.GetElementsByTagName("Signature");


        signed.LoadXml((XmlElement)signatureNodeList[0]);

        X509Certificate2 serviceCertificate = null;
        foreach (KeyInfoClause clause in signed.KeyInfo)
        {
            if (clause is KeyInfoX509Data)
            {
                if (((KeyInfoX509Data)clause).Certificates.Count > 0)
                {
                    serviceCertificate = (X509Certificate2)((KeyInfoX509Data)clause).Certificates[0];
                }
            }
        }


        bool result = signed.CheckSignature(serviceCertificate, true);
        return result;

    }
若我将项目的目标框架设置为.NET3.5或.NET3或.NET2,那个么效果很好。结果是真的。但若我将目标框架更改为.NET4,结果将是错误的。 (我必须使用.NET4)


关于如何解决这个问题有什么想法吗?

尝试显式地为SignedXml类的SignedInfo属性设置规范化方法。。在.Net 2.0和.Net 4.0之间,这里的默认行为似乎发生了变化

signed.SignedInfo.CanonicalizationMethod = Signed.XmlDsigExcC14NTransformUrl;
参考:


从.NET framework 4/4.5中,用于x509证书和其他安全功能的类位于System.IdentityModel.dll中。在提到的名称空间中搜索相应的类。

这是一个已知问题。.NET3.5和.NET4.0之间的规范化实现已更改

我不知道这是否适用于所有的XML签名,但通过我所做的测试,下面的工作是有效的

将以下C14N转换类添加到项目中:

公共类MyXmlDsigC14NTransform:XmlDsigC14NTransform{
静态XmlDocument\u文档;
公共静态XML文档{
设置{
_文件=价值;
}
}
公共MyXmlDsigC14NTransform(){}
公共重写对象GetOutput(){
返回base.GetOutput();
}
公共覆盖无效LoadInnerXml(XmlNodeList nodeList){
LoadInnerXml(节点列表);
}
受保护的重写XmlNodeList GetInnerXml(){
XmlNodeList nodeList=base.GetInnerXml();
返回节点列表;
}
公共XmlElement GetXml(){
返回base.GetXml();
}
公共覆盖无效加载输入(对象obj){
int n;
bool fDefaultNS=真;
xmlement元素=((XmlDocument)obj).DocumentElement;
if(element.Name.Contains(“SignedInfo”)){
XmlNodeList DigestValue=element.GetElementsByTagName(“DigestValue”,element.NamespaceURI);
字符串strHash=DigestValue[0]。InnerText;
XmlNodeList nodeList=\u document.GetElementsByTagName(element.Name);
对于(n=0;n}
我解决了这个问题,将相同的名称空间从签名标记添加到SignedInfo。 像这样:

之前:

之后:

为了检查NET 4.0+上的签名,您必须更改规范化方法的上下文,因此必须按以下方式初始化signedXml对象:

XmlNodeList signatureNodeList = xmlDoc.GetElementsByTagName("Signature");

SignedXml signedXml = new SignedXml((XmlElement)signatureNodeList[0]);

signedXml.LoadXml((XmlElement)signatureNodeList[0]);

//Then you proceed your check as usual

我也有同样的问题,但这些答案对我都没有帮助。在这种情况下,它是否工作取决于我使用的操作系统,而不是.Net版本

我已通过在app.config中添加以下代码来启用SignedXML日志,以查看后面发生的情况:

<system.diagnostics>
        <sources>
            <source name="System.Security.Cryptography.Xml.SignedXml" switchName="XmlDsigLogSwitch">
                <listeners>
                    <add name="logFile" />
                </listeners>
            </source>
        </sources>
        <switches>
            <add name="XmlDsigLogSwitch" value="Verbose" />
        </switches>
        <sharedListeners>
            <add name="logFile" type="System.Diagnostics.TextWriterTraceListener" initializeData="XmlDsigLog.txt"/>
        </sharedListeners>
        <trace autoflush="true">
            <listeners>
                <add name="logFile" />
            </listeners>
        </trace>
    </system.diagnostics>
我发现这篇Microsoft支持文章试图修复安全更新3141780引入的错误:

在那篇文章中,在场景2部分中,有两种解决方案,我修复了应用与XPath转换方法相关的注册表项的问题:
HKEY\U本地\U计算机\软件\ Microsoft.NETFramework\Security\SafeTransformMethods@XmlDsigXPathTransform=

您可能会在一个类似的问题中找到帮助:使用什么算法对其进行签名?您好,您可以发布异常调用堆栈吗?如果我读对了,如果你还在寻找的话,我想可能有解决问题的方法。也许通过.Net源代码调试也会给你一个提示。您可以在VisualStudio中的某个地方/以某种方式启用它:但是规范化方法是一个字符串。尝试了这个,没有任何区别(.NET 3.5 reading.NET 4.0 generated Signature)为什么_文档变量是静态的?
XmlNodeList signatureNodeList = xmlDoc.GetElementsByTagName("Signature");

SignedXml signedXml = new SignedXml((XmlElement)signatureNodeList[0]);

signedXml.LoadXml((XmlElement)signatureNodeList[0]);

//Then you proceed your check as usual
<system.diagnostics>
        <sources>
            <source name="System.Security.Cryptography.Xml.SignedXml" switchName="XmlDsigLogSwitch">
                <listeners>
                    <add name="logFile" />
                </listeners>
            </source>
        </sources>
        <switches>
            <add name="XmlDsigLogSwitch" value="Verbose" />
        </switches>
        <sharedListeners>
            <add name="logFile" type="System.Diagnostics.TextWriterTraceListener" initializeData="XmlDsigLog.txt"/>
        </sharedListeners>
        <trace autoflush="true">
            <listeners>
                <add name="logFile" />
            </listeners>
        </trace>
    </system.diagnostics>
System.Security.Cryptography.Xml.SignedXml Information: 17 : [SignedXml#033ec00f, UnsafeTransformMethod] Canonicalization method "http://www.w3.org/TR/1999/REC-xpath-19991116" is not on the safe list. Safe canonicalization methods are: "http://www.w3.org/TR/2001/REC-xml-c14n-20010315", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments", "http://www.w3.org/2001/10/xml-exc-c14n#", "http://www.w3.org/2001/10/xml-exc-c14n#WithComments", "http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/2000/09/xmldsig#base64", "urn:mpeg:mpeg21:2003:01-REL-R-NS:licenseTransform", "http://www.w3.org/2002/07/decrypt#XML".