简体   繁体   English

在Java中为ws-security UsernameToken实现密码摘要

[英]Implementing password digest for ws-security UsernameToken in Java

I am trying to make a call to a ws-security secured webservice from a server which unfortunately does not support this natively. 我试图从服务器上调用ws-security安全的Web服务,不幸的是,该服务器本身不支持此服务。 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. 我采用的方法是在添加带有ws-security元素的过程中实现一个.jsp,它充当实际端点URL的反向代理。

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. 这似乎工作得很好,并且我相信我已经使用正确的名称空间等正确构建了XML。我已经通过将XML与SOAP-UI生成的XML进行比较来验证了这一点。

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. 使用NOnce,xsd:dateTime和密码以及以下代码使用相同的输入时,我得到的结果与SOAP-UI的结果不同。

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 我认为问题在于实现前两个元素的哈希,如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. 请注意,随机数使用其解码值的八位位组序列进行哈希处理,而时间戳使用元素内容中指定的UTF8编码的八位位组序列进行哈希处理。

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. 如果您可以提供源代码,那将是理想的选择。

I'll take a crack at it without SOAP-UI. 我将在没有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. DigestUtils.sha()将允许您使用字符串,但是该字符串必须正确编码。 When you wrote the nonce, you were calling StringBuffer.append(Object) which ends up calling byte[].toString() . 当您编写随机数时,您正在调用StringBuffer.append(Object) ,最终该调用了byte[].toString() StringBuffer.append(Object) byte[].toString() That gives you something like [B@3e25a5 , definitely not what you want. 那会给您类似[B@3e25a5东西,绝对不是您想要的东西。 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. 请注意,下面的示例使用org.apache.commons.codec.binary.Base64 ,而不是您使用的Base64类。 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));

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() . 但是, java.nio.ByteBuffer导致了我的问题,所以我修改了代码以使用基本的byte[] ,这些基本的byte[]通过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! 我在java.nio.ByteBuffer中遇到的问题是,尽管'buf.position()'返回了适当数量的字节, byte[] toHash通过buf.get(toHash)注入到byte[] toHash所有字节均为0s!

Thanks very much for your assistance. 非常感谢您的协助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM