Я пытаюсь проверить 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());
Я как бы потерялся здесь. Заранее спасибо.