Implementing password digest for ws-security UsernameToken in Java
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));
Stian Sigvartsen
Updated on November 22, 2022Comments
-
Stian Sigvartsen over 1 year
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.
-
John Watts almost 12 yearsCan 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.
-
-
Stian Sigvartsen almost 12 yearsThanks 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!
-
John Watts almost 12 yearsI 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?
-
Stian Sigvartsen almost 12 yearsI'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?
-
John Watts almost 12 yearsI would suggest posting this as a separate question, but yes it sounds incorrect.