1

I am trying to make a call to a ws-security secured webservice from a server which unfortunately does not support this natively. The approach I have taken is to implement a .jsp which acts as reverse proxy to the actual end point URL, in the process adding the element with ws-security elements.

This seems to be working quite well and I am confident I've constructed the XML correctly with the correct namespaces etc. I've verified this by comparing the XML with XML produced by SOAP-UI.

The problem is in implementing the password digest generator. I don't get the same result as what SOAP-UI does using the same inputs for NOnce, xsd:dateTime and password, and the following code.

StringBuffer passwordDigestStr_ = new StringBuffer();

// First append the NOnce from the SOAP header
passwordDigestStr_.append(Base64.decode("PzlbwtWRpmFWjG0JRIRn7A=="));

// Then append the xsd:dateTime in UTC timezone
passwordDigestStr_.append("2012-06-09T18:41:03.640Z");

// Finally append the password/secret
passwordDigestStr_.append("password");

System.out.println("Generated password digest: " + new String(com.bea.xbean.util.Base64.encode(org.apache.commons.codec.digest.DigestUtils.sha(passwordDigestStr_.toString())), "UTF-8"));

I think the problem is with implementing the hashing of the first two elements as explained by http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf

Note that the nonce is hashed using the octet sequence of its decoded value while the timestamp is hashed using the octet sequence of its UTF8 encoding as specified in the contents of the element.

If anyone could help me solve this problem that would be great because it's beginning to drive me crazy! It would be ideal if you could provide source code.

Stian Sigvartsen
  • 29
  • 1
  • 1
  • 4
  • Can you please post sample input and output values from SOAP-UI? That way we can try to help with just Java and your code, not SOAP-UI. – John Watts Jun 09 '12 at 23:42

2 Answers2

9

I'll take a crack at it without SOAP-UI. The input to the hash function is supposed to be bytes, not a string. DigestUtils.sha() will allow you to use a string, but that string must be properly encoded. When you wrote the nonce, you were calling StringBuffer.append(Object) which ends up calling byte[].toString(). That gives you something like [B@3e25a5, definitely not what you want. By using bytes everywhere, you should avoid this problem. Note that the example below uses org.apache.commons.codec.binary.Base64, not the Base64 class you were using. It doesn't matter, that's just the one I had handy.

ByteBuffer buf = ByteBuffer.allocate(1000);
buf.put(Base64.decodeBase64("PzlbwtWRpmFWjG0JRIRn7A=="));
buf.put("2012-06-09T18:41:03.640Z".getBytes("UTF-8"));
buf.put("password".getBytes("UTF-8"));
byte[] toHash = new byte[buf.position()];
buf.rewind();
buf.get(toHash);
byte[] hash = DigestUtils.sha(toHash);
System.out.println("Generated password digest: " + Base64.encodeBase64String(hash));
John Watts
  • 8,717
  • 1
  • 31
  • 35
  • Thanks for the quick reply. I've tried the snippet and it produces yet another password digest to my code and that of SOAP-UI. I did think the problem I am facing has something to do with character encoding. I can see that my approach with using StringBuffer is clearly flawed. Any chance you could setup a SOAP-UI and see if your algorithm produces equal results? Maybe I set up SOAP-UI wrong! – Stian Sigvartsen Jun 10 '12 at 16:14
  • I tried downloading it but it didn't work right away and I don't want to spend a bunch of time messing with it. Can you just attach some sample values of input and output from your copy of SOAP UI? – John Watts Jun 12 '12 at 02:23
  • I've posted an answer and awarded you points. I experienced a secondary issue whilst testing this in terms of data/time representation. This webservice client runs in the UK and we are currently UTC+1 = BST (British Summer Time). Howver, at present the webservice expects a dateTime values with a 'Z' suffix on the representation so I would have expected to need to send a date formatted as one hour in the past (UTC). However, it still wants the hour component to be the BST hour representation which I find odd. Do you agree this is not in accordance with XML Schema dateTime data type? – Stian Sigvartsen Jul 26 '12 at 10:00
  • I would suggest posting this as a separate question, but yes it sounds incorrect. – John Watts Jul 26 '12 at 11:38
0

Apologies for the delay in replying, especially considering your initial quick response. I have now been able to get this to work using the essence of your approach to avoid any character encoding issues. However, java.nio.ByteBuffer caused me issues so I modified the code to use basic byte[]s which I combined using System.arrayCopy(). The problem I faced with java.nio.ByteBuffer was that despite 'buf.position()' returning an appropriate number of bytes, all the bytes injected into byte[] toHash through buf.get(toHash) were 0s!

Thanks very much for your assistance.

ifixthat
  • 6,137
  • 5
  • 25
  • 42
Stian Sigvartsen
  • 29
  • 1
  • 1
  • 4