I have rtfm, but I still have problems. I am re-reading the manual, but posting here because what I am doing is not working. I was provided with the xsd and wsdl file for the SOAP service. I have never implemented a client that requires digital signatures. I wrote a soaphandler to change the title of the envelope, but I cannot understand what I'm doing wrong.
The soap consumer told me that the canoncalization xml message passed to the signature generation should look like this:
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"></ds:SignatureMethod>
<ds:Reference URI="#secinfo" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"></ds:DigestMethod>
<ds:DigestValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">ZwOJboUtw1RlDspibqbyaWrKIog=</ds:DigestValue>
<ds:Transforms xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:XPath xmlns:ds="http://www.w3.org/2000/09/xmldsig#">//*[@id='secinfo']/child::*/text()</ds:XPath>
</ds:Transform>
</ds:Transforms>
</ds:Reference>
</ds:SignedInfo>
The xml I created looks something like this:
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
<ds:Reference URI="#secinfo">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>ZwOJboUtw1RlDspibqbyaWrKIog=</ds:DigestValue>
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
<ds:XPath>//*[@id='secinfo']/child::*/text()</ds:XPath>
</ds:Transform>
</ds:Transforms>
</ds:Reference>
</ds:SignedInfo>
, , . , SOAPElement "ds" uri, , . addAttribute ( "xmlns: ds", "url" ); .
@Override
public boolean handleMessage(SOAPMessageContext context) {
try {
if (messageOutbound(context)) {
SOAPFactory factory = SOAPFactory.newInstance();
SOAPMessage soapMsg = context.getMessage();
SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope();
SOAPHeader soapHeader = soapEnv.getHeader();
if (soapHeader == null) {
soapHeader = soapEnv.addHeader();
}
String serverURI = "service.messages";
soapEnv.addNamespaceDeclaration("urn", serverURI);
String timeStamp = generateTimeStamp();
timeStamp = "201703221758";
String prefix = "wsse";
String uri = "http://schemas.xmlsoap.org/ws/2002/04/secext";
SOAPElement security = factory.createElement("Security", prefix, uri);
uri = "http://www.w3.org/2000/09/xmldsig#";
SOAPElement signedInfo = factory.createElement("SignedInfo", "ds", uri);
SOAPElement canoncalized = factory.createElement("CanonicalizationMethod", "ds", uri);
canoncalized.setAttribute("Algorithm", "http://www.w3.org/2001/10/xml-exc-c14n#");
canoncalized.addNamespaceDeclaration("ds", uri);
SOAPElement signatureMethod = factory.createElement("SignatureMethod", "ds", uri);
signatureMethod.setAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1");
SOAPElement reference = factory.createElement("Reference", "ds", uri);
reference.setAttribute("URI", "#secinfo");
SOAPElement digestMethod = factory.createElement("DigestMethod", "ds", uri);
digestMethod.setAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#sha1");
SOAPElement digestValue = factory.createElement("DigestValue", "ds", uri);
String userString = "USER=" + userID + ";CORR=" + corrNo + ";TIMESTAMP=" + timeStamp;
String digestVal = createDigest("sha1", userString);
digestValue.setValue(digestVal);
SOAPElement transforms = factory.createElement("Transforms", "ds", uri);
SOAPElement transform = factory.createElement("Transform", "ds", uri);
transform.setAttribute("Algorithm", "http://www.w3.org/TR/1999/REC-xpath-19991116");
SOAPElement xPath = factory.createElement("XPath", "ds", uri);
xPath.setValue("//*[@id='secinfo']/child::*/text()");
transform.addChildElement(xPath);
transforms.addChildElement(transform);
reference.addChildElement(digestMethod);
reference.addChildElement(digestValue);
reference.addChildElement(transforms);
signedInfo.addChildElement(canoncalized);
signedInfo.addChildElement(signatureMethod);
signedInfo.addChildElement(reference);
SOAPElement signature = factory.createElement("Signature", "ds", uri);
final StringWriter sw = new StringWriter();
TransformerFactory.newInstance().newTransformer().transform(new DOMSource(signedInfo),
new StreamResult(sw));
String s = sw.toString();
s = s.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "");
System.out.println(s);
SOAPElement signatureValue = factory.createElement("SignatureValue", "ds", uri);
String canonValue = canonicalize(s);
signatureValue.setValue(createSignature("rsa-sha1", canonValue));
SOAPElement keyInfo = factory.createElement("KeyInfo", "ds", uri);
SOAPElement keyName = factory.createElement("KeyName", "ds", uri);
keyName.setValue("BLAHBLAHBLAH");
SOAPElement userNameToken = factory.createElement("UsernameToken", "t", "http://schemas.xmlsoap.org/ws/2002/04/secext");
userNameToken.setAttribute("id", "secinfo");
SOAPElement userInfo = factory.createElement("UserInfo", "t", "http://schemas.xmlsoap.org/ws/2002/04/secext");
userInfo.setValue(userString);
signature.addChildElement(signedInfo);
signature.addChildElement(signatureValue);
keyInfo.addChildElement(keyName);
signature.addChildElement(keyInfo);
security.addChildElement(signature);
userNameToken.addChildElement(userInfo);
security.addChildElement(userNameToken);
soapHeader.addChildElement(security);
soapMsg.saveChanges();
System.out.println("Trying to print message.");
ByteArrayOutputStream out = new ByteArrayOutputStream();
soapMsg.writeTo(out);
String strMsg = new String(out.toByteArray());
System.out.println(strMsg);
System.out.println("End of handleMessage.");
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
.