XMLDSig X509SerialNumber слишком велик, чтобы быть int, не проходит проверка XSD

Я пытаюсь создать XMLDSig с помощью сертификата X509. Я запустил дословный пример из MS (http://msdn.microsoft.com/en-us/library/system.security.cryptography.xml.x509issuerserial.aspx), который генерирует приведенный ниже XML. Проблема с XML заключается в том, что поле X509SerialNumber слишком длинное, чтобы быть целым, а 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 по следующему URL-адресу:

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!");
        }
    }
}

person jhilden    schedule 05.03.2013    source источник


Ответы (2)


Согласно RFC 5280 можно ожидать, что серийные номера будут содержать длинные целые числа:

Пользователи сертификатов ДОЛЖНЫ иметь возможность обрабатывать значения serialNumber до 20 октетов. Соответствующие CA НЕ ДОЛЖНЫ использовать значения serialNumber длиннее 20 октетов.

(раздел 4.1.2.2 о серийном номере)

Ваш серийный номер 7262040306 8401703770 1384536728 07553309 состоит всего из 38 цифр, которые, даже если бы они были шестнадцатеричными цифрами, образуют число, легко вписывающееся в целое число длиной 20 байтов.

В синтаксисе и обработке подписи XML (второе издание)файл схемы) элемент X509SerialNumber определяется как

<element name="X509SerialNumber" type="integer"/>

Что по определению integer допускает произвольные целочисленные значения:

целое число получено от десятичного путем фиксации значения FractionDigits равным 0. Это приводит к стандартной математической концепции. целых чисел. пространство значений целого числа - это бесконечное множество {..., - 2, -1,0,1,2, ...}. базовый тип целого числа - десятичный.

(раздел 3.3.13 XML-схемы, часть 2: Типы данных)

Таким образом, вы можете захотеть проверить свой файл схемы или валидатор XSD.

ИЗМЕНИТЬ

Хотя ваш код основан на синтаксисе и обработке XML-подписи вместо Синтаксис и обработка подписи XML (второе издание) как я отвечу, это не имеет значения, потому что в обоих case X509SerialNumber определяется как integer без дополнительных ограничений.

Таким образом, это проблема вашего валидатора. Я не знаю, ошибка ли это или просто какая-то конфигурация или настройка.

person mkl    schedule 06.03.2013
comment
мкл, спасибо за ответ. Я обновил вопрос с помощью файла XSD, который я использую, и кода, который я использую для проверки XSD. Возможно, я что-то не так делаю при проверке XSD? - person jhilden; 07.03.2013
comment
@jhilden Ваша версия XMLdsig также определяет X509SerialNumber как integer. Таким образом, это проблема вашего валидатора. Я не знаю, ошибка ли это или просто какая-то конфигурация или настройка. - person mkl; 07.03.2013
comment
Привет, вы когда-нибудь решали это? Сегодня у меня была такая же проблема. Я изо всех сил пытаюсь поверить, что библиотеки .NET System.Xml виноваты .... Кроме того, у меня такая же ошибка проверки с подключаемым модулем XML для Notepad ++ - так что это 2 валидатора, которые якобы сейчас глючны ... - person Simon Green; 29.04.2015
comment
извини, Саймон, но я не думаю, что когда-либо решал эту проблему. Возможно, ключевым моментом является обновление XSD вручную. - person jhilden; 29.04.2015
comment
Хм, не люблю это делать, но мне кажется, что это единственный доступный вариант. Не могу поверить, что валидатор .NET xsd работает некорректно уже 2 года и не исправлен! Я изменю xsd на строку и на числовую проверку после разбора - person Simon Green; 29.04.2015
comment
Привет, @SimonGreen. У меня такая же проблема с .NET. Я также применил обходной путь, и меня также интересует элегантное решение. Если кто-то настаивает, пожалуйста, упомяните меня, чтобы я был в курсе. Кстати, ответ mkl правильный (w3.org/2001/XMLSchema.xsd ) - person dani herrera; 01.07.2015

Валидатор .NET XSD для xs:integer пытается проверить значение, анализируя его как C # decimal (https://referencesource.microsoft.com/#System.Xml/System/Xml/Schema/DataTypeImplementation.cs,2874, https://источникссылок.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/ - это то место, где можно найти проблему, за которую нужно проголосовать (или не найдя ее, создайте новую).

person bartonjs    schedule 22.05.2017