XMLDSig X509SerialNumber 太大而不能成为 int,XSD 验证失败
Posted
技术标签:
【中文标题】XMLDSig X509SerialNumber 太大而不能成为 int,XSD 验证失败【英文标题】:XMLDSig X509SerialNumber too large to be an int, fails XSD validation 【发布时间】:2013-02-20 03:23:24 【问题描述】:我正在尝试使用 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>
我正在使用来自以下 URL 的 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!");
【问题讨论】:
【参考方案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
的定义确实允许任意整数值:
integer 是通过将 fractionDigits 的值固定为 0 从 decimal 派生。这导致整数的标准数学概念。整数的值空间是无限集...,-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
而没有进一步的限制。
因此,这是您的验证器的问题。是错误还是只是一些配置或自定义问题,我不知道。
【讨论】:
mkl,谢谢您的回复。我已经用我正在使用的 XSD 文件和我用来验证 XSD 的代码更新了这个问题。我是否在 XSD 检查中做错了什么? @jhilden 您的 XMLdsig 版本还将X509SerialNumber
定义为 integer.
因此,这是您的验证器的问题。我不知道这是一个错误还是仅仅是一些配置或自定义问题。
嗨,你解决过这个问题吗?我今天也遇到了同样的问题。我很难相信 .NET System.Xml 库有问题....此外,我在 Notepad++ 的 XML 插件中遇到了同样的验证错误 - 所以这是 2 个据称现在有问题的验证器......
对不起,西蒙,但我认为我从来没有解决过这个问题。也许手动更新 XSD 是关键。
嗯,不喜欢这样做,但这似乎是我唯一可用的选择。不敢相信 .NET xsd 验证器行为不端已经 2 年了,但没有得到修复!我将在解析后将 xsd 更改为说字符串和数字检查【参考方案2】:
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 位十进制数字的十进制数字(即 18 位的 ·totalDigits )。但是,··最低限度符合··处理器··可以·设置应用程序定义的最大十进制位数限制...
如果您觉得这阻碍了这些类型的有效使用(不仅仅是测试场景,尽管这些也很重要)https://github.com/dotnet/corefx/issues/ 将是搜索要投票的问题的地方(或找不到问题,创建一个新的一)。
【讨论】:
以上是关于XMLDSig X509SerialNumber 太大而不能成为 int,XSD 验证失败的主要内容,如果未能解决你的问题,请参考以下文章
SAML 请求中缺少 xmlns:ds="http://www.w3.org/2000/09/xmldsig#"