Реализация дайджеста пароля для ws-security UsernameToken в Java

Я пытаюсь позвонить в защищенный веб-сервис с защитой ws с сервера, который, к сожалению, не поддерживает эту функцию. Подход, который я выбрал, заключается в реализации .jsp, который действует как обратный прокси к фактическому URL конечной точки, в процессе добавления элемента с элементами ws-security.

Кажется, это работает довольно хорошо, и я уверен, что я правильно сконструировал XML с правильными пространствами имен и т. Д. Я проверил это, сравнив XML с XML, созданным SOAP-UI.

Проблема заключается в реализации генератора паролей. Я не получаю тот же результат, что и SOAP-UI, использующий те же входные данные для NOnce, xsd: dateTime и password и следующий код.

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

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.

Если бы кто-нибудь мог помочь мне решить эту проблему, это было бы здорово, потому что это начинает сводить меня с ума! Было бы идеально, если бы вы могли предоставить исходный код.

Ответы на вопрос(2)

Решение Вопроса

Я попробую это сделать без SOAP-UI. Предполагается, что входные данные для хеш-функции должны быть байтами, а не строкой.DigestUtils.sha() позволит вам использовать строку, но эта строка должна быть правильно закодирована. Когда вы написали одноразовый номер, вы звонилиStringBuffer.append(Object) который заканчивает тем, что звонилbyte[].toString(), Это дает вам что-то вроде[[email protected]определенно не то, что вы хотите. Используя байты везде, вы должны избегать этой проблемы. Обратите внимание, что в примере ниже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));

Извиняюсь за задержку с ответом, особенно учитывая ваш первоначальный быстрый ответ. Теперь я смог заставить это работать, используя суть вашего подхода, чтобы избежать любых проблем с кодировкой символов. Тем не мение,java.nio.ByteBuffer вызвало у меня проблемы, поэтому я изменил код для использования основныхbyte[]ы, которые я использовал в сочетанииSystem.arrayCopy(), Проблема, с которой я столкнулсяjava.nio.ByteBuffer было ли это несмотря на "buf.position ()" возвращая соответствующее количество байтов, все байты введены вbyte[] toHash черезbuf.get(toHash) были 0s!

Большое спасибо за вашу помощь.

Ваш ответ на вопрос