我正在尝试使用X509证书创建XMLDSig。我运行MS(http://msdn.microsoft.com/en-us/library/system.security.cryptography.xml.x509issuerserial.aspx)的逐字示例,它生成下面的XML。 XML的问题在于X509SerialNumber字段太长而不能成为int,这是XSD指定的必须的。因此,当我尝试对签名进行XSD验证时,它会失败。
我得到的错误信息是: “http://www.w3.org/2000/09/xmldsig#:X509SerialNumber”元素无效 - 值“72620403068401703770138453672807553309”根据其数据类型“http://www.w3.org/2001/XMLSchema:integer”无效 - 字符串“72620403068401703770138453672807553309”不是有效的整数值。
如何获取X509SerialNumber的正确值?
提前致谢!
<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>zSI5ZAMmQ+8u7R2rP7aAPT6nNQw=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>Tx4rqqDae4vdi5sTjARf0AlBiIGWnx2D8ET+ogGD9FtjrX4ZuYlsOG03Zk5KPKDpC/T45XlWaZpZdCtvAWtv0zwL1/jXxlU2BomQFNXm7rb9YoqlTh8nISStiZKizhmMQynW6GRsXGIpkK37Hnip4c8H1U+eSC/taKW4oyUmg40W64+ZyntovpBt2GqIJQu4AFvMfiF2azV9pg/qZ7IYNOgwmrUG6F0t2RhT2hqR9YRePjrfyIebZvYrLwjTQPXGOzzc2utRILAEhzGNSqsvpf5YeVrmuX75E8Zs3JuaicXu4mgDPYxNNVE2membNQMl6ggllfFjxPnvIofbb/KJ4Q==</SignatureValue>
<KeyInfo>
<X509Data>
<X509IssuerSerial>
<X509IssuerName>CN=XMLDSIG_Test</X509IssuerName>
<X509SerialNumber>72620403068401703770138453672807553309</X509SerialNumber>
</X509IssuerSerial>
<X509Certificate>MIIDIDCCAgygAwIBAgIQNqIuTm7QSrZClm5/JrLZHTAJBgUrDgMCHQUAMCMxITAfBgNVBAMeGABYAE0ATABEAFMASQBHAF8AVABlAHMAdDAeFw0xMDAxMDEwNjAwMDBaFw0yMDAxMDEwNjAwMDBaMCMxITAfBgNVBAMeGABYAE0ATABEAFMASQBHAF8AVABlAHMAdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMl9hSOn53/2W2//EC8HUgwO7Hwpqx0/yTwth0w3amefwZcfu/+7k9rB+mnviCy6G/9uGzb0Mld+L3RVXisAx9zr2l6LVFjzImY1alwZ01z6AiDdllFPqO7BoSJSozMh0k+vdVQYR3lvgLNyKxXmrTayIWhioQeteIo6HuChz8HI/DNdzoO8axGbLuhy34pogG1gAQr3pTn16Pkd4Mu02KoRz90dryt09wuAk1P/jsePYHBeLQeJSLGojWp1sqypxr25FQiqJantyVLXRRmv7IauTTThSSNrREMcTzbpCx7B4tvyocNwGZysYcdJVsyjbxJRLqutQDlID6QykqkL9O8CAwEAAaNYMFYwVAYDVR0BBE0wS4AQ0N2edJbnLN9AE7hLcICPNaElMCMxITAfBgNVBAMeGABYAE0ATABEAFMASQBHAF8AVABlAHMAdIIQNqIuTm7QSrZClm5/JrLZHTAJBgUrDgMCHQUAA4IBAQC5Nf5SGjqIzQqVnwJbP22RqSHrITAPlymGYfP/qST8Q9V5h5aX8idcGMt3lShUbexXAlKcpQLO4ZzUrjjP3H5Jc659sRSDaeqHGXE0ZMTJpvwA871WH/sGZ8tB7/yuHVsP9hPTImwwDCWx9mYDz8LxpvK11beq/tEilZQxLTvMP0MuT5A6YdCcCc4GkeDV0KVFF+VLEO8OkaWDVXUNMe/AJBHrXuHbQPrUb7s67FKH+b/2GVjBBkM6YI9JtL/A96Y2uf6drhOz6C7wfky2XQOe/7v87/YGEshObBawBA1/OB1AVa+A2WVOosisEGi7iJqszQTdF6TLqGB5eDsiZCH2</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
我正在使用以下网址中的XSD:
http://www.w3.org/2000/09/xmldsig#
这是验证XSD的代码:
XmlElement xmlDigitalSignature = signedXml.GetXml();
var xEl = XElement.Parse(xmlDigitalSignature.OuterXml);
var xDoc = XDocument.Load(xEl.CreateReader());
XSDValidator.ValidateSignature(xDoc);
public class XSDValidator
{
public static void ValidateSignature(XDocument document)
{
var schemaSet = new XmlSchemaSet();
var assm = Assembly.GetExecutingAssembly();
using (var stream = assm.GetManifestResourceStream("JayTest1.XMLSignature.xsd"))
{
schemaSet.Add(XmlSchema.Read(stream, null));
}
var isValid = true;
string errorMessage = null;
document.Validate(schemaSet, (o, e) =>
{
errorMessage = e.Message;
isValid = false;
});
if (!isValid)
{
Console.WriteLine("XSD is not valid: " + errorMessage);
}
else
{
Console.WriteLine("GOOD!");
}
}
}
答案 0 :(得分:1)
根据RFC 5280 序列号可以包含长整数:
证书用户必须能够处理最多20个八位字节的serialNumber值。符合CA不得使用超过20个八位字节的serialNumber值。
(序列号第4.1.2.2节)
您的序列号 7262040306 8401703770 1384536728 07553309 只有38位数字,即使它们是十六进制数字,也能形成一个容易装入20字节长整数的数字。
在XML Signature Syntax and Processing (Second Edition)(以及schema file)中,元素X509SerialNumber
被定义为
<element name="X509SerialNumber" type="integer"/>
根据integer
的定义,它允许任意整数值:
通过将 fractionDigits 的值固定为0,整数从十进制 派生。这会导致整数的标准数学概念。整数的值空间是无限集{..., - 2,-1,0,1,2,...}。整数的基类型是十进制的。
(XML Schema Part 2: Datatypes的第3.3.13节)
因此,您可能需要检查架构文件或XSD验证程序。
修改强>
虽然我的答案是基于XML-Signature Syntax and Processing而不是XML Signature Syntax and Processing (Second Edition),但这确实没有区别,因为在这两种情况下X509SerialNumber
被定义为integer
没有进一步限制。
因此,这是验证者的问题。无论是一个bug还是仅仅是一些配置或定制问题,我都不知道。
答案 1 :(得分:0)
xs:integer
的.NET XSD验证程序尝试通过将其解析为C#decimal
(https://referencesource.microsoft.com/#System.Xml/System/Xml/Schema/DataTypeImplementation.cs,2874,https://referencesource.microsoft.com/#System.Xml/System/Xml/XmlConvert.cs,3e8716fb1936c48d)来验证该值。
小数的正值范围为79,228,162,514,264,337,593,543,950,335,负数为79,228,162,514,264,337,593,543,950,335(https://docs.microsoft.com/en-us/dotnet/api/system.decimal?view=netframework-4.7)或28.79位。
此限制确实超过http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#decimal的最小值:
注意:所有·符合最低要求的处理器·必须支持十进制数,最少18个十进制数字(即,totalDigits·18)。但是,·最低限度符合·处理器·可能·在它们准备支持的最大小数位数上设置应用程序定义的限制...
如果您认为这会抑制这些类型的有效用法(不仅仅是测试方案,尽管这些也很重要)https://github.com/dotnet/corefx/issues/将是搜索问题以进行upvote(或找不到,创建)的地方一个新的)。