1

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

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

问题在于实现密码摘要生成器。我没有得到与 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"));

我认为问题在于实现前两个元素的散列,如http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf所解释

请注意,nonce 使用其解码值的八位字节序列进行散列,而时间戳使用其在元素内容中指定的 UTF8 编码的八位字节序列进行散列。

如果有人能帮我解决这个问题,那就太好了,因为它开始让我发疯了!如果您可以提供源代码,那将是理想的。

4

2 回答 2

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));
于 2012-06-10T00:13:02.073 回答
0

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

非常感谢您的帮助。

于 2012-07-26T10:00:25.337 回答