我正在尝试从服务器调用ws-security安全的Web服务,遗憾的是,该服务器本身不支持此服务。我采用的方法是实现一个.jsp,它作为实际端点URL的反向代理,在这个过程中添加了带有ws-security元素的元素。
这似乎工作得很好,我相信我已经使用正确的命名空间等正确构造了XML。我已经通过比较XML与SOAP-UI生成的XML来验证这一点。
问题在于实现密码摘要生成器。我没有得到与使用相同的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"));
我认为问题在于实现前两个元素的散列,如http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf所述
请注意,使用其解码值的八位位组序列对nonce进行哈希处理,而时间戳使用其元素内容中指定的UTF8编码的八位位组序列进行哈希处理。
如果有人能帮助我解决这个问题会很好,因为它开始让我发疯!如果你能提供源代码,那将是理想的。
答案 0 :(得分:9)
我会在没有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));
答案 1 :(得分:0)
对回复延迟表示歉意,特别是考虑到您最初的快速反应。我现在已经能够使用您的方法的本质来避免任何字符编码问题。但是,java.nio.ByteBuffer
导致了我的问题,因此我修改了代码以使用基本的byte[]
,我使用System.arrayCopy()
进行了组合。我遇到java.nio.ByteBuffer
的问题是,尽管'buf.position()'返回了适当数量的字节,但注入byte[] toHash
到buf.get(toHash)
的所有字节都是0!
非常感谢您的协助。