XML Сбой проверки подписи в некоторых сообщениях и передача в другие - PullRequest
2 голосов
/ 12 марта 2020

У меня есть приложение java, которое регистрируется на сервере. NET для целей лицензирования. Сервер лицензирования отвечает подписью xml. Для некоторых сообщений приложение Java не может проверить подпись, но для других оно работает нормально.

Вот сообщение, которое можно проверить без проблем (отформатированные и замененные конфиденциальные данные):

<AuthorizeResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <LicenseKey>replaced actual data</LicenseKey>
    <Message i:nil="true" />
    <MessageGuid>67d5b7bd-33bd-467b-a3fc-842f0f4782e3</MessageGuid>
    <Nonce>0</Nonce>
    <Success>true</Success>
    <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>QQL4nxJbna/VUR/b3caorWjHb0Q=</DigestValue>
            </Reference>
        </SignedInfo>
        <SignatureValue>
            nui/m6DvMBbKjncklq1/1Bo4Bzq8C1Z+dhL0c3YMM2wDdDMhC7ob201r3XnDijFcuhz8BomNbE2Br51Y9+R1wPq2JuQ0K8037f7WmQW5M1l+5Dvz9bFrK1oKExKudg9iRNv0iYcgMxY6x0m3tyQTC6KnH/uBtALbQeNLTti+ho4=
        </SignatureValue>
    </Signature>
</AuthorizeResponse>

Вот сообщение о сбое проверки (в формате):

<AuthorizeResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <LicenseKey i:nil="true" />
    <Message>Already using license on max number of systems. Running on
        systems:127.0.0.1;192.168.1.8;host.docker.internal;1127.0.0.1;192.168.1.8;host.docker.internal;2</Message>
    <MessageGuid>7f5d0e32-6117-4204-85e1-dec5c57c053e</MessageGuid>
    <Nonce>0</Nonce>
    <Success>false</Success>
    <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>JJ81DxbusvrVSCZUy/3nobs71FU=</DigestValue>
            </Reference>
        </SignedInfo>
        <SignatureValue>
            aYhs9Vri70bSqsRcVyE8HpQgs0KIQQfmTgJiIv2QzP4Aa172T5ntiii0EU4CJn28N3tXSJK4wmbxZBOvZGnyYuBOv/5jWEFyeUuNAwmw/r+HdVKctBD0BRmSSq+fqQpMjlJmyT/3RL1S250KhCFB05NhvSxk0IbZUei/4RpWwcc=
        </SignatureValue>
    </Signature>
</AuthorizeResponse>

Код подписи в C#:

        public static void SignXmlDocument(string privateKey, XmlDocument xmlDoc)
        {
            SignedXml signedXml = new SignedXml(xmlDoc);

            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
            rsaKey.FromXmlString(privateKey);
            signedXml.SigningKey = rsaKey;

            Reference reference = new Reference {Uri = ""};
            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
            reference.AddTransform(env);
            signedXml.AddReference(reference);
            signedXml.ComputeSignature();
            XmlElement xmlDigitalSignature = signedXml.GetXml();
            // ReSharper disable once PossibleNullReferenceException
            xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
        }

Код проверки в Java ( jboss неверно):

    private static boolean verifyXmlFromStream(InputStream SignedXmlDocumentStream, boolean jboss)
    {
        try
        {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            Document sourceDoc = dbf.newDocumentBuilder().parse(SignedXmlDocumentStream);

            NodeList nl = sourceDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
            if (nl.getLength() == 0)
                throw new Exception("Cannot find Signature element");

            XMLSignatureFactory factory = getSignatureFactory(jboss);
            DOMValidateContext valContext = new DOMValidateContext(new KeyValueKeySelector(), nl.item(0));
            XMLSignature signature = factory.unmarshalXMLSignature(valContext);
            boolean coreValidity = signature.validate(valContext);

            if (!coreValidity)
                log.warn("Signature failed core validation!"); // error?
            return coreValidity;
        }
        catch (Exception e)
        {
            log.error(e);
            return false;
        }
    }

    private static XMLSignatureFactory getSignatureFactory(boolean jboss)
        throws ClassNotFoundException,
               InstantiationException,
               IllegalAccessException
    {
        if (jboss)
        {
            log.debug("Getting XML security provider using JBoss friendly method.");
            return XMLSignatureFactory.getInstance("DOM");
        }
        else
        {
            String provider = System.getProperty("jsr105Provider",
                    "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
            return XMLSignatureFactory.getInstance("DOM",
                    (Provider)Class.forName(provider).newInstance());
        }
    }

Есть идеи, почему подпись работает правильно для одних сообщений и терпит неудачу с другими? Я попытался по-другому кодировать документ и отправить второе сообщение без ';' символ без различий в поведении.

Редактировать: Я также пытался создать HttpContent, возвращаемый моим сервером, несколькими различными способами на случай изменения форматирования пробелов при создании моего StringContent.

1 Ответ

0 голосов
/ 20 марта 2020

Каким-то образом белые новые строки удалялись из узла сообщения после подписания. Я не совсем уверен, почему, поэтому я просто создаю сообщение без новых строк.

...