Не удается разрешить элемент с идентификатором SigConf при проверке SOAP XML подписи - PullRequest
0 голосов
/ 28 апреля 2020

Я пытаюсь проверить xml ответ от SOAP службы. Что-то вроде этого.

<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Header>
        <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <ds:Signature Id="Signature-15840779" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:SignedInfo>
                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                    <ds:Reference URI="#id-15840780">
                        <ds:Transforms>
                            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>jSLXXX4Q=</ds:DigestValue>
                    </ds:Reference>
                    <ds:Reference URI="#SigConf-XXX">
                        <ds:Transforms>
                            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>dQ99RXXXLi4=</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>LONGLONGSINGATUREVALUEASASVASDSAFGASFWHATEVER
</ds:SignatureValue>
                <ds:KeyInfo Id="KeyId-F6CXXX64">
                    <wsse:SecurityTokenReference wsu:Id="STRId-F6CXXX9765" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
                        <ds:X509Data>
                            <ds:X509IssuerSerial>
                                <ds:X509IssuerName>C=TR,O=XXX,CN=Test Payment Systems CA</ds:X509IssuerName>
                                <ds:X509SerialNumber>7XXX1</ds:X509SerialNumber>
                            </ds:X509IssuerSerial>
                        </ds:X509Data>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
            </ds:Signature>
            <wsse11:SignatureConfirmation Value="ALSOALONGLONGSIGNATUREVALUEWHATEVERDOESNTMATTER" wsu:Id="SigConf-XXX" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"/>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body wsu:Id="id-15840780" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <WHATEVERXXRESPONSE xmlns="http://serveraddress/services/endpoint/">...
        </WHATEVERXXRESPONSE>
    </soapenv:Body></soapenv:Envelope>

Итак, я нашел этот ответ на stackoverflow и попытался применить его. Это мой код проверки:

private boolean validateSignature(org.w3c.dom.Node signatureNode, org.w3c.dom.Node bodyTag, PublicKey publicKey) {
    boolean signatureIsValid = false;
    try {
        // Create a DOM XMLSignatureFactory that will be used to unmarshal the
        // document containing the XMLSignature
        String providerName = System.getProperty
                ("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
                (Provider) Class.forName(providerName).newInstance());

        // Create a DOMValidateContext and specify a KeyValue KeySelector
        // and document context
        DOMValidateContext valContext = new DOMValidateContext(new X509KeySelector(publicKey), signatureNode);

        Element bodyElement =  (Element) bodyTag;
        valContext.setIdAttributeNS(bodyElement, WSU_NAMESPACE, "Id");

        Attr idAttr = bodyElement.getAttributeNode("wsu:Id");
        bodyElement.setIdAttributeNode(idAttr, true);

        // Unmarshal the XMLSignature.
        XMLSignature signature = fac.unmarshalXMLSignature(valContext);
        // Validate the XMLSignature.
        signatureIsValid = signature.validate(valContext);

    } catch (Exception ex) {
        LOGGER.error("An Error Raised while Signature Validation");
        LOGGER.error("Cause: " + ex.getCause());
        LOGGER.error("Message: " + ex.getMessage());
        LOGGER.error("error",ex);
    }

    return signatureIsValid;
}

Я не могу понять, как и почему, но мой код проверки не выполняется на signature.validate(valContext) и выдает это исключение:

javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID SigConf-XXX

Я думаю, это связано с тем, что SigConf не найден ни в узле подписи, ни в теле, поскольку он находится в положении, аналогичном сигнатуре. Но когда я добавляю узлы по-другому, включая SignatureConfirmation, он даже не работает и жалуется, что я ввел неправильные параметры.

Насколько я могу судить по отладке, я " Мы сделали в другом Referance, который начинается с #id-XXX, он работает просто как finde, потому что он определен в теге body.

Кстати, вот как вызвать мой метод:

                SOAPPart soapPart = soapMessage.getSOAPPart();
                SOAPEnvelope envelope = soapPart.getEnvelope();

                //NodeList nodeList = envelope.getHeader().getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");

                validateSignature(envelope.getElementsByTagName("ds:Signature").item(0), envelope.getBody(),extractPublicKeyFromCertificate());

Я как бы потерялся здесь. Заранее спасибо.

...