未声明 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(或文件路径) - 它将使用XmlReaderSettings
和DtdProcessing = DtdProcessing.Prohibit
读取该文件。我们需要将其更改为DtdProcessing.Ignore
或DtdProcessing.Parse
。之后,您的验证方法将适用于目标 xsd 和 xml 文件,无需任何更改(如果 xml 与 xsd 不匹配,将正确失败)。
【讨论】:
第一次尝试就可以了!多谢兄弟!上帝保佑你!以上是关于未声明 XML 签名元素的主要内容,如果未能解决你的问题,请参考以下文章
如何计算对包括 SignedProperties 的 XML XAdES 的签名?