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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10964434/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 03:14:52  来源:igfitidea点击:

Implementing password digest for ws-security UsernameToken in Java

javasoapws-securityusernametoken

提问by Stian Sigvartsen

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.

我试图从一个服务器调用 ws-security 安全的 web 服务,不幸的是它本身不支持这个。我采用的方法是实现一个 .jsp,它充当实际端点 URL 的反向代理,在此过程中添加带有 ws-security 元素的元素。

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.

问题在于实现密码摘要生成器。我没有得到与 SOAP-UI 使用相同的 NOnce、xsd:dateTime 和密码输入以及以下代码所做的结果相同的结果。

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.

如果有人能帮我解决这个问题,那就太好了,因为它开始让我发疯!如果能提供源代码就更好了。

回答by John Watts

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.

我会在没有 SOAP-UI 的情况下尝试一下。散列函数的输入应该是字节,而不是字符串。DigestUtils.sha()将允许您使用字符串,但该字符串必须正确编码。当你写 nonce 时,你正在调用StringBuffer.append(Object)它最终调用byte[].toString(). 这给了你类似的东西[B@3e25a5,绝对不是你想要的。通过在任何地方使用字节,您应该避免这个问题。请注意,下面的示例使用的是org.apache.commons.codec.binary.Base64,而不是您使用的 Base64 类。没关系,那只是我手头的那一个。

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));

回答by Stian Sigvartsen

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.ByteBuffercaused 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.ByteBufferwas that despite 'buf.position()' returning an appropriate number of bytes, all the bytes injected into byte[] toHashthrough buf.get(toHash)were 0s!

对于延迟回复深表歉意,特别是考虑到您最初的快速回复。我现在已经能够使用你的方法的本质来让它工作,以避免任何字符编码问题。但是,这java.nio.ByteBuffer给我带来了问题,所以我修改了代码以使用byte[]我使用System.arrayCopy(). 我面临的问题java.nio.ByteBuffer是,尽管 'buf.position()' 返回了适当数量的字节,但注入到byte[] toHashthrough 的所有字节buf.get(toHash)都是 0!

Thanks very much for your assistance.

非常感谢您的帮助。