未声明 XML 签名元素

Posted

技术标签:

【中文标题】未声明 XML 签名元素【英文标题】:XML Signature element is not declared 【发布时间】:2017-07-15 09:40:41 【问题描述】:

我使用 Visual StudioXML 工具创建了 XSD。我使用以下 C# 代码来验证 XML 并遇到此错误。

错误

元素未声明 'http://www.w3.org/2000/09/xmldsig#:Signature'。

所以我的问题是如何修复它,因为在编辑模式下 XML 100% 有效?

谢谢!

C#

  private void buttonValidateXML_Click(object sender, EventArgs e)
        
            try
                        
                bool result = IsValidXml2(textBoxSignedXML.Text, textBoxXSDFile.Text, "");
                rtbValidationResult.Text = result.ToString();
            
            catch (Exception ex)
            
                rtbValidationResult.Text = ex.Message;
            
        

public static bool IsValidXml2(string xmlFilePath, string xsdFilePath, string namespaceName)
        
            var xdoc = XDocument.Load(xmlFilePath);
            var schemas = new XmlSchemaSet();
            schemas.Add(namespaceName, xsdFilePath);

            bool result = true;
            xdoc.Validate(schemas, (sender, e) =>
            
                result = false;
            );

            return result;
        

XML

<?xml version="1.0" encoding="utf-8"?>
<Envelope version="1">
  <Deposit>
    <ClientId>1234567890123</ClientId>
    <Account>0045678</Account>
    <Currency>USD</Currency>
    <Total>5000.00</Total>
    <SignedDate>2016-02-15</SignedDate>     
    <Cheques>
      <Cheque>
        <Images>
          <Front>
            SUkqAAgAAAAPAP4ABAABAAAAAAAAAAABBAABAAAAfQUAAAEBBAABAAAAWgIAAAIBAwABAAAAAQAA
            AAMBAwABAAAABAAAAAYBAwABAAAAAAAAAA4BAgAhAAAA0AAAABEBBAABAAAAAAIAABIBAwABAAAA
            AQAAABUBAwABAAAAAQAAABYBBAABAAAAWgIAABcBBAABAAAAvi8AABoBBQABAAAAAAEAABsBBQAB
            EdF0fRG0R0YRdH2R2XzaI6OxRQAQAQA=
          </Front>
          <Back>
            SUkqAAgAAAAOAP4ABAABAAAAAAAAAAABBAABAAAAgQUAAAEBBAABAAAAVAIAAAIBAwABAAAAAQAA
            AAMBAwABAAAABAAAAAYBAwABAAAAAAAAABEBBAABAAAAAAEAABIBAwABAAAAAQAAABUBAwABAAAA
            AQAAABYBBAABAAAAVAIAABcBBAABAAAAcggAABoBBQABAAAAwAAAABsBBQABAAAA0AAAACgBAwAB
            AAAAAgAAAAAAAAAAAAAAAAAAAAAAyAAAAAEAAAAAAAAAAAAAAMgAAAABAAAAAAAAAAAAAAAAAAAA
            AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//LZCdO1f7iRrKXTqt//pePx///9lNoL487Ajh
            jFyzUrtwg+6gg9VmvCIWA42XMwziSUEEw7GoIcSUWZ3Y0oKmGR3LToGVC2LhkK6H4sorQNRUMLjH
            LTGzlpv3RFCcH4NLB9hvLTmD8tMgOsG+WVaR5AweTcEWMMfaDQxDIx5NwVQx8OMPeGFHLSUlLcSS
            1JtNV/9/rrffuO+h9bx////kfvABABAA
          </Back>
        </Images>
        <MicrCodeCmc>123456789012345678901234567890</MicrCodeCmc>
        <Amount>465.22</Amount>
        <PaymentDate>2016-02-15</PaymentDate>
        <EmissionDate>2016-02-15</EmissionDate>
      </Cheque>
      <Cheque>
        <Images>
          <Front>
            SUkqAAgAAAAPAP4ABAABAAAAAAAAAAABBAABAAAAfQUAAAEBBAABAAAAWgIAAAIBAwABAAAAAQAA
            AAMBAwABAAAABAAAAAYBAwABAAAAAAAAAA4BAgAhAAAA0AAAABEBBAABAAAAAAIAABIBAwABAAAA
            AQAAABUBAwABAAAAAQAAABYBBAABAAAAWgIAABcBBAABAAAAvi8AABoBBQABAAAAAAEAABsBBQAB
            EdF0fRG0R0YRdH2R2XzaI6OxRQAQAQA=
          </Front>
          <Back>
            SUkqAAgAAAAOAP4ABAABAAAAAAAAAAABBAABAAAAgQUAAAEBBAABAAAAVAIAAAIBAwABAAAAAQAA
            AAMBAwABAAAABAAAAAYBAwABAAAAAAAAABEBBAABAAAAAAEAABIBAwABAAAAAQAAABUBAwABAAAA
            AQAAABYBBAABAAAAVAIAABcBBAABAAAAcggAABoBBQABAAAAwAAAABsBBQABAAAA0AAAACgBAwAB
            AAAAAgAAAAAAAAAAAAAAAAAAAAAAyAAAAAEAAAAAAAAAAAAAAMgAAAABAAAAAAAAAAAAAAAAAAAA
            AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//LZCdO1f7iRrKXTqt//pePx///9lNoL487Ajh
            jFyzUrtwg+6gg9VmvCIWA42XMwziSUEEw7GoIcSUWZ3Y0oKmGR3LToGVC2LhkK6H4sorQNRUMLjH
            LTGzlpv3RFCcH4NLB9hvLTmD8tMgOsG+WVaR5AweTcEWMMfaDQxDIx5NwVQx8OMPeGFHLSUlLcSS
            1JtNV/9/rrffuO+h9bx////kfvABABAA
          </Back>
        </Images>
        <MicrCodeCmc>123456789012345678901234567890</MicrCodeCmc>
        <Amount>99999999999</Amount>
        <PaymentDate>2016-02-15</PaymentDate>
        <EmissionDate>2016-02-15</EmissionDate>
      </Cheque>
    </Cheques>
  </Deposit>   
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue>TVO2Gssf5TUdXFYG/PrHDyqYFqs=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>KwQInN03ywa0u0t4HedxgE1fOU7XYLQScKuQ6vdYoIZME5Hm5jpFeX2ORA2U+BO7JNjmFilTW05VntS3k98YCZhNXH9Iw/YEC1nw4JJLzygYbbCftkiY5v5+b494mQPryCtscwTtbziW6QilILSFDGmco2JopRfVe+qfdN/JyB1HXhUfApyNEsw/cJLj6aaz5ivN1sLFgAlikbwCNpF+mRnZY5u7/S8uT8WhEyK32EcatdjzKbP0PwnIlumhOpUMerWeLZ7neuJq6R/IuFgZ1Y5U6ppyuOjhtiHp4glC/uNUS/y7jMzG29thWBkEtSE9AcEt2IZ0HOEZE3kdFXufjA==</SignatureValue>
  </Signature>
</Envelope>

XSD

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:tns="http://example.com/ct-required"
           xmlns:xmime="http://www.w3.org/2005/05/xmlmime" >

  <xs:import namespace="http://www.w3.org/2005/05/xmlmime"
            schemaLocation="http://www.w3.org/2005/05/xmlmime"/>

    <xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>

  <xs:simpleType name="PNGPictureType"
          xmime:expectedContentTypes="image/png">
    <xs:restriction base="xs:base64Binary"/>
  </xs:simpleType>

  <xs:simpleType name="Money">
    <xs:restriction base="xs:decimal">
      <xs:totalDigits value="13" />
      <xs:fractionDigits value="2" />
      <xs:minInclusive value="0.00" />
      <xs:maxInclusive value="99999999999.99" />
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="Currency">
        <xs:annotation>
            <xs:documentation>Currency Code: ISO 4217</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:enumeration value="USD" />
            <xs:enumeration value="UYU" />
            <xs:minLength value="3" />
            <xs:maxLength value="3" />
        </xs:restriction>
    </xs:simpleType>

  <xs:element name="Envelope">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Deposit" minOccurs="1" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="ClientId" type="xs:unsignedLong" />
              <xs:element name="Account" type="xs:unsignedLong" />
              <xs:element name="Currency" type="Currency" />
              <xs:element name="Total" type="Money" />
              <xs:element name="SignedDate" type="xs:date" />
              <xs:element name="Cheques">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="Cheque">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="Images">
                            <xs:complexType>
                              <xs:sequence>
                                <xs:element name="Front" type="PNGPictureType" />
                                <xs:element name="Back" type="PNGPictureType" />
                              </xs:sequence>
                            </xs:complexType>
                          </xs:element>
                          <xs:element name="MicrCodeCmc" type="xs:string" />
                          <xs:element name="Amount" type="Money" />
                          <xs:element name="PaymentDate" type="xs:date" />
                          <xs:element name="EmissionDate" type="xs:date" />
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element xmlns:q1="http://www.w3.org/2000/09/xmldsig#" ref="q1:Signature" />
      </xs:sequence>
      <xs:attribute name="version" type="xs:unsignedByte" use="required" />
    </xs:complexType>
  </xs:element>
</xs:schema>

更新 #1

我尝试了不同的方法,但没有任何乐趣。

即使我将 XSD 引用到本地文件,它也不起作用。我看到了同样的错误。

 <xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212 file:///C:/Temp/xmldsig-core-schema.xsd"/>

更新 #2

即使我使用这种方法也没有乐趣。

 public static bool IsValidXml1(string xmlFilePath, string xsdFilePath, string namespaceName)
        
            XDocument xdoc = null;
            var settings = new XmlReaderSettings();
            settings.DtdProcessing = DtdProcessing.Ignore;
            settings.ProhibitDtd = false;

            try
            
                using (XmlReader xr = XmlReader.Create(xmlFilePath, settings))
                
                    xdoc = XDocument.Load(xr);
                    var schemas = new XmlSchemaSet();
                    schemas.Add(namespaceName, xsdFilePath);
                    schemas.Add(@"http://www.w3.org/2000/09/xmldsig#", @"D:\Temp\xmldsig-core-schema.xsd");
                    xdoc.Validate(schemas, null);

                    return true;
                                
            
            catch (XmlSchemaValidationException ex)
            
                // throw;
            

            return false;
        

【问题讨论】:

@HenkHolterman 好吧...我必须使用 XSD 文件来验证 XML... @dimi - 您将 XmlReader 修复应用于错误的输入文件。 @HenkHolterman:如果您提供另一种机制来解析名称空间,而不仅仅是完整的xs:import,那么您可以在不更改 XSD 的情况下成功纠正问题。但是,最具互操作性的修复方法是完成 xs:import as I've shown;然后,OP 和其他方将能够仅使用 XML 和 XSD 进行验证,而无需额外的机制将导入的 XSD 绑定到命名空间。如果您可以在 XSD 修复中添加特定的 XmlReader 修复,那么整个问题可能会得到解决。 @HenkHolterman 您可能对我的解决方案感兴趣,因为它通过修改 dsig xsd 避免了您的混乱。 我已经想通了 - 并向 OP 指出了如何解决它。您不需要外部 XmlReader,只需要第二个。 【参考方案1】:

你很亲密。在您的 XSD 中,只需替换,

<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" />

<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" 
           schemaLocation=
    "http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"/>

您的 XSD 将不再出现该错误,并且您的 XML 将对您的 XSD 有效。

说明

XSD 可以通过xs:import and xs:include 组成。在这两种情况下,必须使用必需的schemaLocation 属性指定引用的 XSD 的位置,而 OP 的原始 XSD 中缺少该属性。如上图添加xs:import/@schemaLocation,错误就消除了。


更新 #1:

当您切换到使用本地 XSD 时,您在 xs:import 中犯了一个错误:

改变

 <xs:import namespace="http://www.w3.org/2000/09/xmldsig#"
            schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212 
                            file:///C:/Temp/xmldsig-core-schema.xsd"/>

 <xs:import namespace="http://www.w3.org/2000/09/xmldsig#"
            schemaLocation="file:///C:/Temp/xmldsig-core-schema.xsd"/>

(您在具有名称空间位置的 XML 文档中遵循 @xsi:schemaLocation 的示例;xs:import/@schemaLocation 不同。)


更新 #2:

所以我的问题是如何修复它,因为在编辑模式下 XML 100% 有效?

也许这就是脱节。在 Visual Studio 中编辑 XML 文件不会自动根据 XSD 对其进行验证。您需要在代码中或通过验证 XML 编辑器(例如 Oxygen XML Editor 或 XML Spy)来执行此操作。

此外,您的 C# 验证代码可能存在问题。见Validating an XML against referenced XSD in C#

【讨论】:

你能解释一下吗?我从来没有这样做过。 很抱歉,它不起作用。它说:警告命名空间w3.org/2000/09/xmldsig#的导入架构未解析 @Dimi:以上更正对于消除您的XSD 中的错误是必要的,并且一旦进行,您的XML 根据您更正的XSD 是有效的。我已经确认这与您的代码无关。我建议您使用独立的 XML 编辑器针对您的 XSD 验证您的 XML,以确保您在更新 XSD 时没有出错。 How to reference a local XML Schema file correctly 答案已更新。最后提示:强烈建议您首先按照我所展示的那样正确获取 XML 和 XSD,然后担心您的 C# 代码。 我已经准确地向您展示了修复 XSD 所需要做的事情,以便您的 XML 能够验证。 我需要继续前进——您已经询问了一系列后续问题,而这个网站是不适用于正在进行的交流。对任何未来的问题使用单独的问题。谢谢,祝你好运。【参考方案2】:

如果您不想将任何内容更改为 xsd 或 xml - 请执行以下操作:

    (可选)从w3 site 下载xsd 并保存到本地磁盘。 W3 站点非常慢,因为全球许多软件不断请求这些模式。如果您将直接使用该 xsd - 您通常会因超时而失败。一些验证工具已经在本地缓存了此类架构,但没有 .NET 验证器。

    通过以下方式从 UPDATE 2 修改您的验证方法:

    public static bool IsValidXml1(string xmlFilePath, string xsdFilePath, string namespaceName)
    
        XDocument xdoc = null;
        var settings = new XmlReaderSettings();
        settings.DtdProcessing = DtdProcessing.Ignore;
    
        try
        
            using (XmlReader xr = XmlReader.Create(xmlFilePath, settings))
            
                xdoc = XDocument.Load(xr);
                var schemas = new XmlSchemaSet();                    
                schemas.Add(namespaceName, xsdFilePath);                   
                using (var fs = File.OpenRead(@"D:\Temp\xmldsig-core-schema.xsd")) 
                using (var reader = XmlReader.Create(fs, new XmlReaderSettings() 
                    DtdProcessing = DtdProcessing.Ignore // important
                )) 
                    schemas.Add(@"http://www.w3.org/2000/09/xmldsig#", reader);
                
    
                xdoc.Validate(schemas, null);
    
                return true;
            
        
        catch (XmlSchemaValidationException ex)
        
            // throw;
        
    
        return false;
    
    

您必须使用 XmlReader 而不是直接添加该架构,因为如果您直接添加(如在更新 2 中) - 它将无法解析 DTD 块,因为当您将 XmlSchema 添加到 XmlSchemaSet 时使用url(或文件路径) - 它将使用XmlReaderSettingsDtdProcessing = DtdProcessing.Prohibit 读取该文件。我们需要将其更改为DtdProcessing.IgnoreDtdProcessing.Parse。之后,您的验证方法将适用于目标 xsd 和 xml 文件,无需任何更改(如果 xml 与 xsd 不匹配,将正确失败)。

【讨论】:

第一次尝试就可以了!多谢兄弟!上帝保佑你!

以上是关于未声明 XML 签名元素的主要内容,如果未能解决你的问题,请参考以下文章

打字稿:未找到导出/JSX 元素类型没有任何构造或调用签名

使用 Ant 构建已签名和未签名的版本

无法验证包,未使用苹果提交证书签名

如何计算对包括 SignedProperties 的 XML XAdES 的签名?

type 'typeof globalThis' 没有索引签名

XML解析