Создание подписи xml с префиксом ds

Я создал подпись xml с помощью signedxml, и проверка работает хорошо. Моя подписьxml выглядит следующим образом:

<Signature Id="orderSignature" 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>0r1BZecYgC4FzPIxuU9DYIbVqUE=</DigestValue>
                        </Reference>
                    </SignedInfo>
                    <SignatureValue>B+SreGOR7+QEnvo0zMgJsNgZ4gbA1leOifLGd09HG8lZD0ZxsBkcR0aauTgwRgeOefKSwah+KEqAlZvRNykgPjBmY9BJ2g6OfRdvm/mSj7ecDuq/Ic1vo5bHeFJHzr8qbS7IKS/hl/BOx+06yg5rFbVeQGYypznNLIKrjS5cfDbo11e6tpLWswZMxhly8c+FHuMKzAJKOw4spbebgVT4p/vGYsPekTRtvtLtqp1yVl1za8xWkqXmbPPxwio7rXFpKWAqdLQiHYW0cs8ARXUo2jSjete+m4+wQ3QpN4Wfj8Cs3+bYsh01r1XHUG48w3PGt11+trlIEABCaQrhgj9xzg==</SignatureValue>
                    <KeyInfo>
                        <KeyValue>
                            <RSAKeyValue>
                                <Modulus>z9KDoRUO4alAwhL2Nq2fIAwsbecLuWYnzwKEX2WsUOWmhXksD+uYqjRqrKpV9j2tWFf6Ba87zEEa5xPOgD9Jj5naq6tDuH9q48u2gosC3vohPTNXL1I1sj9NTYIFNN+xcf/hi7fPQa/yq5lPOwN45kblee8Z6MqVt6Jk5ytQ+jMT6ZMStL6dOASKbwROfb0uhdmOieX60CGNAbdrn/ei2Vr2EOVmHSB1ZqZ0EhaFTKK5PPuiDlptl+bH0KBqkYEcMgzGMgxNJbDM/MlHgXWh9IWTS/A64awy8xUEQwq9QCibYzI5WCDceyTiNSAVhBQDMEX4YyWDj52sceKEK/q9NQ==</Modulus>
                                <Exponent>AQAB</Exponent>
                            </RSAKeyValue>
                        </KeyValue>
                        <X509Data>
                            <X509IssuerSerial>
                                <X509IssuerName>CN=Mali Mühür Elektronik Sertifika Hizmet Sağlayıcısı - Sürüm 1, C=TR</X509IssuerName>
                                <X509SerialNumber>97806797770378</X509SerialNumber>
                            </X509IssuerSerial>
                            <X509SubjectName>CN=Bimtel İletişim Ve Bilişim Ticaret Limited Şirketi, SERIALNUMBER=1750422091</X509SubjectName>
                            <X509Certificate>MIIFrTCCBJWgAwIBAgIGWPRrcA6KMA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNVBAYTAlRSMU0wSwYDVQQDDERNYWxpIE3DvGjDvHIgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMTAeFw0xMTEwMTkxMjQ1NDVaFw0xNjEwMTcxMjQ1NDVaMFYxEzARBgNVBAUTCjE3NTA0MjIwOTExPzA9BgNVBAMMNkJpbXRlbCDEsGxldGnFn2ltIFZlIEJpbGnFn2ltIFRpY2FyZXQgTGltaXRlZCDFnmlya2V0aTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM/Sg6EVDuGpQMIS9jatnyAMLG3nC7lmJ88ChF9lrFDlpoV5LA/rmKo0aqyqVfY9rVhX+gWvO8xBGucTzoA/SY+Z2qurQ7h/auPLtoKLAt76IT0zVy9SNbI/TU2CBTTfsXH/4Yu3z0Gv8quZTzsDeOZG5XnvGejKlbeiZOcrUPozE+mTErS+nTgEim8ETn29LoXZjonl+tAhjQG3a5/3otla9hDlZh0gdWamdBIWhUyiuTz7og5abZfmx9CgapGBHDIMxjIMTSWwzPzJR4F1ofSFk0vwOuGsMvMVBEMKvUAom2MyOVgg3Hsk4jUgFYQUAzBF+GMlg4+drHHihCv6vTUCAwEAAaOCAnkwggJ1MB8GA1UdIwQYMBaAFEYgqVMbKAwcrvIoUYOzHr7yUxR8MB0GA1UdDgQWBBRv135w613ZEQPsNPW+8TDIFkKEDzAOBgNVHQ8BAf8EBAMCB4AwggEzBgNVHSAEggEqMIIBJjCCASIGC2CGGAECAQEFBwQBMIIBETAqBggrBgEFBQcCARYeaHR0cDovL2RlcG8ua2FtdXNtLmdvdi50ci9pbGtlMIHiBggrBgEFBQcCAjCB1R6B0gBCAHUAIABzAGUAcgB0AGkAZgBpAGsAYQAgAGkAbABlACAAaQBsAGcAaQBsAGkAIABzAGUAcgB0AGkAZgBpAGsAYQAgAHUAeQBnAHUAbABhAG0AYQAgAGUAcwBhAHMAbABhAHIBMQBuATEAIABvAGsAdQBtAGEAawAgAGkA5wBpAG4AIABiAGUAbABpAHIAdABpAGwAZQBuACAAdwBlAGIAIABzAGkAdABlAHMAaQBuAGkAIAB6AGkAeQBhAHIAZQB0ACAAZQBkAGkAbgBpAHoALjAMBgNVHRMBAf8EAjAAMBYGA1UdJQQPMA0GC2CGGAECAQEFBzIBMEEGA1UdHwQ6MDgwNqA0oDKGMGh0dHA6Ly9kZXBvLmthbXVzbS5nb3YudHIva3VydW1zYWwvbW1lc2hzLXMxLmNybDCBggYIKwYBBQUHAQEEdjB0MDwGCCsGAQUFBzAChjBodHRwOi8vZGVwby5rYW11c20uZ292LnRyL2t1cnVtc2FsL21tZXNocy1zMS5jcnQwNAYIKwYBBQUHMAGGKGh0dHA6Ly9jaXNkdXBtbXMxLmt1cnVtc2FsLmthbXVzbS5nb3YudHIwDQYJKoZIhvcNAQELBQADggEBAFX0arwcDDLRbYHOkxb3Os4t3kMxPG7VzBAcgiPCV/ph1xda1S7IyXTk54L6OsXtsW/JBvf9+mjufAQXPwUl1AoqndBOkzYuOYv5ZXpK0Uzb1yV+XiLZtKp44wv2FeaEN5D/nyMAwi6ckGE959/JnXV5AAURBwgrnuOcksryJwOyRV78JAu28UL0fflDdmLR8qZKUUDdDzAhHTZzXBjF1GtHyEGtg3nJKO13ZZba6HXbv6dP2J7ZgFTTeyobTh5MsnBIedSItxfAxUhls7M8L3h0X42Dkx28nZw7zG1n55TIPrahihjR99qYGVnf5lnfYOt5/dhkeOazxam+QookoBI=</X509Certificate>
                        </X509Data>
                    </KeyInfo>
                </Signature>

Но мне нужно сгенерировать XML-подпись с префиксом «ds:».

Я не смог найти решение этой проблемы в stackoverflow.

Как получить xml-подпись с префиксом? Возможно ли это с помощью библиотеки signedxml (System.Security.Cryptography.Xml),,

Или есть какая-нибудь библиотека, которую я могу сгенерировать?

Спасибо за любой совет..


person Turgay Gençer    schedule 25.05.2012    source источник
comment
возможный дубликат .NET Signed XML Prefix   -  person Eugene Mayevski 'Callback    schedule 26.05.2012
comment
а вот в остальных вопросах решения нет ,,,   -  person Turgay Gençer    schedule 28.05.2012
comment
Я не вижу проблем в вашем вопросе. Вы спрашиваете, как добавить префикс, а упомянутый вопрос и принятый ответ на этот вопрос идентичны вашему текущему вопросу.   -  person Eugene Mayevski 'Callback    schedule 28.05.2012
comment
Я не смог решить свою проблему с указанным вопросом, и в stackoverflow есть много повторяющихся вопросов по этому вопросу.   -  person Turgay Gençer    schedule 28.05.2012
comment
у вас есть ответ: stackoverflow.com/ questions/10799894/ рядом с этим вопросом есть дубликат вашего собственного вопроса...   -  person albciff    schedule 05.09.2014


Ответы (3)


Я действительно не понимаю, почему вы хотите добавить префикс ds в пространство имен.

Имея это:

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature">
  <ds:SignedInfo Id="SignedInfo">
 <ds:CanonicalizationMethod ...

Полностью эквивалентен:

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="Signature">
   <SignedInfo Id="SignedInfo">
 <CanonicalizationMethod ...

В первом случае вы должны указать ds для элементов в http://www.w3.org/2000/09/xmldsig#, во втором случае это пространство имен является пространством имен по умолчанию, поэтому каждый элемент в xml без объявленного префикса принадлежит этому пространству имен.

Кроме того, вы говорите, что вам нужно добавить префикс ds, чтобы иметь XAdES-BES, и вы что-то комментируете о разнице между подписями xmldsig и xades. Вы должны знать, что XAdES — это всего лишь спецификация, в которой говорится, какие атрибуты необходимы подписи XMLDSIG, чтобы стать подписью XAdES. Грубо говоря, XAdES — это подпись XMLDSIG, которая включает в себя: <Object http://www.w3.org/2000/09/xmldsig#>, которая будет содержать весь набор подходящих свойств, некоторые из которых подписаны (signedProperties), а некоторые — неподписаны (unsignedProperties). Для случая XAdES-BES необходимо добавить <xades:SigningCertificate xmlns:xades="http://uri.etsi.org/01903/v1.3.2#"> внутрь элемента <xades:SignedProperties>.

Здесь я привожу вам пример подписи XAdES-BES «без» префикса ds.

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="Signature">
<SignedInfo Id="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 Id="SignedProperties-Reference" Type="http://uri.etsi.org/01903/v1.2.2#SignedProperties" URI="#SignedProperties">
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <DigestValue>fiKTaqJzLSmC73cMXZSzjhd877w=</DigestValue>
    </Reference>
    <Reference Id="SignedDataObject-Reference-1" URI="DetachedObjectReference-1">
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <DigestValue>8ruIS/4MRp2wAwVX4/pTCYxTyWc=</DigestValue>
    </Reference>
</SignedInfo>
<SignatureValue Id="DocumentSignatureValue">
    R40YdEEEl0YIZVdl4pm3yyF7qGAG8ZN8PPf0aBRXbvRgdIcvJZtI5AS5NexaO5T4O0gMHWRIKjNb
    2QzlfwxlQ3/KqMW4W0QkMLpF4csBpXt9bJ3t+smEeTnxkBcQRXAw5v9kwf20mfz1LtIUhbsU/PMd
    YwaGCsItF2rzl3rtcq4=
</SignatureValue>
<KeyInfo Id="KeyInfo">
    <X509Data>
        <X509Certificate>
            MIIIUTCCBzmgAwI...
        </X509Certificate>
    </X509Data>
    <KeyValue>
        <RSAKeyValue>
            <Modulus>
              pb0cJiodddCDVe/t+7...
            </Modulus>
            <Exponent>AQAB</Exponent>
        </RSAKeyValue>
    </KeyValue>
</KeyInfo>
<Object>
    <xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" Id="QualifyingProperties" Target="#Signature">
        <xades:SignedProperties Id="SignedProperties">
            <xades:SignedSignatureProperties>
                <xades:SigningCertificate>
                    <xades:Cert>
                        <xades:CertDigest>
                            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                            <DigestValue>UZq4NIL9eVVA7aJixPeiUTM3nOM=</DigestValue>
                        </xades:CertDigest>
                        <xades:IssuerSerial>
                            <X509IssuerName>XXXXXXXXXXXX....</X509IssuerName>
                            <X509SerialNumber>705964899...</X509SerialNumber>
                        </xades:IssuerSerial>
                    </xades:Cert>
                </xades:SigningCertificate>
            </xades:SignedSignatureProperties>
            <xades:SignedDataObjectProperties/>
        </xades:SignedProperties>
    </xades:QualifyingProperties>
</Object>

Hope this helps,

person albciff    schedule 04.09.2014
comment
Посетил этот вопрос, потому что у меня такая же потребность. В моем случае кто-то, кто написал спецификацию для какой-то организации, подумал, что было бы здорово потребовать, чтобы префикс ds: ДОЛЖЕН использоваться всегда. - person Thuan; 14.10.2017
comment
Есть простая и, вероятно, веская причина, по которой всем нужна версия с префиксом: dss, золотой стандарт для подписи в Европе (с открытым исходным кодом, но Java) использует версию с префиксом, поэтому людям, не являющимся техническими специалистами, может быть трудно объяснить, что она так же действительна, даже перед отчетом о проверке. - person ceztko; 11.12.2020

После долгих исследований я нашел этот ответ. В основном необходимо изменить класс SignedXml, чтобы добавить префикс перед получением значения дайджеста узла SignedInfo.

Метод ComputeSignature будет изменен, чтобы добавить параметр префикса.

public void ComputeSignature(string prefix){...}

Когда этот метод вызывается, он вычисляет значение подписи, анализируя значение узла SignedInfo. Если вы получите это значение без префикса «ds», а затем добавите префикс, вы получите недопустимую подпись, поэтому вам придется добавить префикс. ПЕРЕД получением значения дайджеста узла signedinfo.

Это значение дайджеста генерируется в методе GetC14NDigest, поэтому этот метод будет изменен, чтобы добавить параметр префикса и добавить префикс ДО получения значения дайджеста.

private byte[] GetC14NDigest(HashAlgorithm hash, string prefix)
{
    XmlDocument document = new XmlDocument();
    document.PreserveWhitespace = false;
    XmlElement e = this.SignedInfo.GetXml(); //get the signedinfo nodes
    document.AppendChild(document.ImportNode(e, true));        
    Transform canonicalizationMethodObject = this.SignedInfo.CanonicalizationMethodObject;       
    SetPrefix(prefix, document.DocumentElement); /*Set the prefix before getting the HASH*/
    canonicalizationMethodObject.LoadInput(document);
    return canonicalizationMethodObject.GetDigestedOutput(hash);
}

Итак, теперь у вас есть значение подписи узлов SignedInfo С префиксом «ds», при этом у вас все еще НЕТ xml с префиксом, поэтому, если вы просто вызовете метод GetXml, вы не увидите « ds" и, конечно же, поскольку значение подписи было рассчитано с учетом префикса ds, у вас будет недействительная подпись. Чтобы избежать этого и получить структуру xml с префиксом, вам нужно изменить метод GetXml, добавить параметр префикса и вызвать метод SetPrefix, который добавит префикс «ds» ко всем узлам в Signature Xml.

public XmlElement GetXml(string prefix)
{
    XmlElement e = this.GetXml();
    SetPrefix(prefix, e); //return the xml structure with the prefix
    return e;
}

Я оставлю здесь класс с этими модификациями

ПОЛЬЗОВАТЕЛЬСКИЙ КЛАСС

internal sealed class CustomSignedXml : SignedXml
{
    XmlElement obj = null;
    public CustomSignedXml (XmlDocument xml)
        : base(xml)
    {
    }

    public CustomSignedXml (XmlElement xmlElement)
        : base(xmlElement)
    {

    }

    public XmlElement GetXml(string prefix)
    {
        XmlElement e = this.GetXml();
        SetPrefix(prefix, e);
        return e;
    }

    public void ComputeSignature(string prefix)
    {
        this.BuildDigestedReferences();
        AsymmetricAlgorithm signingKey = this.SigningKey;
        if (signingKey == null)
        {
            throw new CryptographicException("Cryptography_Xml_LoadKeyFailed");
        }
        if (this.SignedInfo.SignatureMethod == null)
        {
            if (!(signingKey is DSA))
            {
                if (!(signingKey is RSA))
                {
                    throw new CryptographicException("Cryptography_Xml_CreatedKeyFailed");
                }
                if (this.SignedInfo.SignatureMethod == null)
                {
                    this.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
                }
            }
            else
            {
                this.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#dsa-sha1";
            }
        }
        SignatureDescription description = CryptoConfig.CreateFromName(this.SignedInfo.SignatureMethod) as SignatureDescription;
        if (description == null)
        {
            throw new CryptographicException("Cryptography_Xml_SignatureDescriptionNotCreated");
        }
        HashAlgorithm hash = description.CreateDigest();
        if (hash == null)
        {
            throw new CryptographicException("Cryptography_Xml_CreateHashAlgorithmFailed");
        }
        this.GetC14NDigest(hash, prefix);
        this.m_signature.SignatureValue = description.CreateFormatter(signingKey).CreateSignature(hash);
    }         

    private byte[] GetC14NDigest(HashAlgorithm hash, string prefix)
    {

        XmlDocument document = new XmlDocument();
        document.PreserveWhitespace = false;
        XmlElement e = this.SignedInfo.GetXml();
        document.AppendChild(document.ImportNode(e, true));               

        Transform canonicalizationMethodObject = this.SignedInfo.CanonicalizationMethodObject;            
        SetPrefix(prefix, document.DocumentElement); //Set the prefix before getting the HASH
        canonicalizationMethodObject.LoadInput(document);
        return canonicalizationMethodObject.GetDigestedOutput(hash);
    }

    private void BuildDigestedReferences()
    {
        Type t = typeof(SignedXml);
        MethodInfo m = t.GetMethod("BuildDigestedReferences", BindingFlags.NonPublic | BindingFlags.Instance);
        m.Invoke(this, new object[] { });
    }

    private void SetPrefix(string prefix, XmlNode node)
    {
       foreach (XmlNode n in node.ChildNodes)
          SetPrefix(prefix, n);
       node.Prefix = prefix;
    }
}

И способ его использования

CustomSignedXml signedXml = new CustomSignedXml();

//compute the signature with the "ds" prefix

signedXml.ComputeSignature("ds");

//get the xml of the signature with the "ds" prefix

XmlElement xmlDigitalSignature = signedXml.GetXml("ds");
person sAlfaro    schedule 15.03.2017
comment
Возможно, вы сможете улучшить качество своего ответа, объяснив больше о том, как работает ваш код. - person Regular Jo; 16.03.2017
comment
Спасибо, я отредактировал свой ответ, надеюсь, теперь он будет более понятным - person sAlfaro; 08.06.2017

попробуйте добавить этот атрибут xmlns:ds="http://www.w3.org/2000/09/xmldsig#" в корневой тег вашего XML-документа, прежде чем подписать его. В моем случае это помогло для подписи в конверте, но я использую Crypto API. Надеюсь, это поможет вам.

person Petr Dokoupil    schedule 08.07.2015