Дайджест-вычисление подписи не выполняется в 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= ) для рассчитанного дайджеста.

Есть идеи?


Дополнительные факты (13.06.2017):

После замечания Маартенса я (пере) написал некоторые классы (фактически скопировал и вставил) и добавил некоторый System.out.println, чтобы иметь «информацию об отладке» во время выполнения. Действительно странный старый стиль и уродливая вещь... Но результат был довольно интересным!

  1. Поток для MessageDigest никогда не устанавливался. Таким образом, это объясняет 2jmj7l5rSw0yVb/vlWAYkK/YBwk=, который является дайджестом для пустой строки с SHA-1 (спасибо, Маартен!)

Затем мне удалось исправить - так что поток теперь установлен в моих скопированных "отладочных" классах.

Результат: если я сейчас отлаживаю свою 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]

Как видите, расчет временной метки верен. Но вариант для тела неправильный.

Возможно, какой-то буфер потока, который не полностью записан?


person jahuer1    schedule 01.06.2017    source источник
comment
исключение/трассировка стека? Воспроизводимый тестовый пример с конфигурацией?   -  person eis    schedule 01.06.2017
comment
Обратите внимание на DOMReference.validate(...): у вас есть this.digestValue {взятое из файла} и this.calcDigestValue {недавно рассчитанное}. Строка this.validationStatus = Arrays.equals(this.digestValue, this.calcDigestValue); результаты false для validationStatus. Кажется, независимо от того, какой файл с подписью мыла вы берете, результат для calcDigestValue всегда равен 2jmj7l5rSw0yVb/vlWAYkK/YBwk=   -  person jahuer1    schedule 01.06.2017
comment
Вы должны убедиться, что ссылки/пространства имен верны в любом сценарии, связанном с проверкой подписи XML. Мне пришлось явно добавить проверки, потому что XML digsig использовал путь, а SOAP — идентификатор элемента (или наоборот?). Если вы получаете одно и то же значение хеш-функции каждый раз, ссылка может быть отключена. Обратите внимание, что значением дайджеста является хэш SHA-1 пустой строки.   -  person Maarten Bodewes    schedule 04.06.2017
comment
Возможно, это последнее из ваших беспокойств на данный момент, но использование SHA-1 для генерации/проверки подписи, конечно же, не является хорошей идеей.   -  person Maarten Bodewes    schedule 04.06.2017
comment
SHA-1 действительно последняя из моих забот... - тем не менее: если проверить подпись, то надо взять ту, с которой она была сделана!   -  person jahuer1    schedule 13.06.2017


Ответы (1)


После некоторых тестов выяснилось, что была дополнительная проблема с кодировкой... :-(((

Исходные подписанные файлы находятся в UTF-8, но, поскольку Windows использует ISO-xyz_whatever, это не соответствует.

Первое исправление - поместить кодировку JVM в скрипт, вызывающий банку, поэтому:

java -Dfile.encoding=UTF8 <programm>.jar
person jahuer1    schedule 15.06.2017
comment
Лучшим решением было бы указать кодировку при преобразовании байтов из файла в символы. Не имея всего кода, я не знаю, где вы ошибаетесь, но обычно это происходит в InputStreamReader. - person Malcolm Smith; 15.06.2017
comment
Если это устранило проблему, вам следует исправить свое приложение, явно указав кодировку, в которой вы читаете файл, а не временную меру переопределения кодировки файла по умолчанию. - person Mark Rotteveel; 15.06.2017
comment
Зная о проблемах с кодировкой, мы адаптировали чтение файлов более 10 лет назад... . Дело в том, что при обновлении сторонних компонентов вылезала ошибка. wss4j с 1.5.8 на 2.1.9; xmlsec в качестве новой зависимости. Там должен быть какой-то очень скрытый баг. С другой стороны, если я запускаю проекты веб-сервисов на компьютере с Windows, которые фактически используют одни и те же классы, проблем не возникает... (!?!?!?) - person jahuer1; 23.06.2017