Дайджест подсчета подписи не работает на Windows, Java 1.8
Работа, которую нужно сделать:
Я получил подписанный запрос SOAP, и я должен проверить, в порядке ли подпись. Отметка времени сообщения SOAP не представляет интереса.
Мое решение до сих пор:
Я создал дочерний класс org.apache.wss4j.dom.engine.WSSecurityEngine, где в методе processSecurityHeader проверка TimestampProcessor не имеет значения:
public class SignatureSecurityEngine extends WSSecurityEngine {
...
public WSHandlerResult processSecurityHeader(Element securityHeader, RequestData requestData) throws org.apache.wss4j.common.ext.WSSecurityException {
...
Processor p = cfg.getProcessor(el);
if (p != null) {
try {
results = p.handleToken((Element) node, requestData, wsDocInfo);
} catch (Exception e){
if (p instanceof TimestampProcessor) {
// it's okay if timestamp is too old
} else {
throw e;
}
}
}
...
На самом деле это всего лишь копия WSSecurityEngine с добавлением try/catch для процессора отметок времени.
У старых версий wss4j и xmlsec это работало нормально.
После обновления версии компонентов я получил следующую странную проблему:
Расчет дайджеста подписи завершается неудачей в org.apache.jcp.xml.dsig.internal.dom.DOMReference.validate(...), если:
- Программа работает на Windows (JRE)
- Я отлаживаю на Windows (JDK)
- Я отлаживаю на Linux (JDK)
НО:
Если программа работает на Linux (JRE), все работает отлично!
Для обоих (Windows/Linux) конфигурация:
- wss4j 2.1.9
- xmlsec 2.0.8
- Версия Java: 1.8.0_131 (сборка 1.8.0_131-b11)
Наблюдение:
Похоже, что для расчетного дайджеста остается стандартное значение ( 2jmj7l5rSw0yVb/vlWAYkK/YBwk=).
Любая идея?
Дополнительные факты (2017-06-13):
После замечаний Мартенса я (пере) написал некоторые классы (фактически скопируйте и вставил) и добавил немного System.out.println, чтобы иметь "отладочную информацию" во время выполнения. Действительно странный старый стиль и ужасная вещь... Но результат был довольно интересным!
- Поток для MessageDigest никогда не был установлен. Так что это объясняет 2jmj7l5rSw0yVb / vlWAYkK / YBwk =, который является дайджестом для пустой строки с SHA-1 (спасибо Maarten!)
Мне удалось тогда исправить - так что поток теперь установлен в моих скопированных "отладочных"-классах.
Результат: если я отлаживаюсь сейчас с помощью моей IDE, функции вычисления!
Но: если я запускаю во время выполнения, проверка завершается неудачно:-(((Причина: расчетное значение не равно ожидаемому.
Дальнейшие наблюдения показали: ев. неправильный расчет зависит от длины данных, для которых должен быть рассчитан дайджест (!?!?!?).
Давайте посмотрим на мой журнал:
*** Digest for Timestamp
VGDOMReference.validate -> transform:
Expected digest: LxfIdEUVsbyLaevptByfIf2L0PA=
Actual digest: LxfIdEUVsbyLaevptByfIf2L0PA=
Reference[#Timestamp-31b20235-a1e2-4ed0-9658-67611572108e]
*** Digest for Body
Expected digest: Yv+zLpkog+xzAdMlSjoIaZntZLs=
Actual digest: sj2Gb0GEyjWuxoCmnBzDY266aG8=
Reference[#Body-c9761a98-46bb-4175-8f8b-bfa9b5c75509]
Как видите, расчет для отметки времени верен. Но тот, который для тела не так.
Возможно какой-нибудь буфер потока, который не полностью записан?
1 ответ
После некоторых тестов выяснилось, что возникла дополнительная проблема с кодировкой...:-(((
Оригинальные подписанные файлы находятся в UTF-8, но в Windows используется ISO-xyz_, что бы не совпадало.
Первое исправление состоит в том, чтобы поместить кодировку JVM в скрипт, который вызывает jar, так что:
java -Dfile.encoding=UTF8 <programm>.jar