Добрый день. Несколько дней не заходил и не нашлось никого объяснить как работает проверка xmldsig?
Dmitrii F скорее всего проблема в неправильном понимании понятия "отсоединенная" применительно к xmldsig формату (который проверяется классом SignedXml). "Отсоединенная" (detached) для xmldsig означает что подпись и подписанный фрагмент взаимно не подчинены. Поэтому отсоединенная подпись может быть как в отдельном файле (
на весь документ), так и внутри исходного (
на фрагмент).
Обратите внимание на полный формат параметра Reference URI - в начале указывается URL файла, затем решетка и идентификатор фрагмента файла, то есть технически возможно подписать любой опубликованный файл в интернете. Если пропущено URL - используется
текущий документ, в котором расположен тег Signature. Если пропушена решетка и идентификатор - берется весь документ. Пустое значение соответственно означает "подписан весь текущий документ". У вас при проверке Reference URI="" внешнего файла с подписью класс signedXml посчитает хэш от внешнего файла с подписью, а не от исходного и понятное дело так как в подписи указан хэш от исходного, то хэши файлов не сходятся.
Поэтому правильно так подписать весь файл:
1) В исходном файле тег Signature включается под тегом самого высокого уровня, в этом случае URI="" и должен присутствовать трансформ enveloped signature, то есть выйдет уже не detached. Проблема тут в том, что каждый валидный документ xml может содержать только один тег самого высокого уровня (не считая текст, специальные конструкции
), поэтому мы не можем просто "прилепить" подпись в конец файла, приходится включать на уровень ниже, где уже будет зависимость и тип enveloped signature.
2) Во внешнем файле
ВНИМАНИЕ! URI должно содержать URL (ну хотя бы имя, считая что файлы в одной папке и это "текущий каталог") подписанного файла! В сообщениях выше есть цитата, что этот вариант не поддерживается SignedXml. С чем и поздравляю.
Для передачи в другие информационные системы вариант 2 неудобен и используется вариант 1. Отмечу однако, стандарт SOAP (и все форматы сервисов на его основе) напрямую запрещает вариант 2, оставляя только вариант 1 или 3 (ниже, отсоединенная подпись фрагмента в том же файле). В этом и ответ почему поддержку варианта 2 не включили в класс - используется крайне редко, но при этом требует много кода и ресурсов.
3)При подписи фрагмента (detached) выглядит примерно так:
Код:<SIMPLE><HELLO id="aaaa"> Hello World </HELLO><Signature ...>...<Reference URI="#aaaa">...</Reference>...</Signature></SIMPLE>
Поэтому предлагаю прервать экскурс в sha алгоритмы подписи и вернуться к гост-2012 - с ним я смогу что-либо посоветовать и выявить проблему, а вот sha в моем решении не поддерживается.
Еще становится любопытно под какие такие задачи в реальной работе криптооперации нужно делать гост-2012 через openssl (в которой нет встроенной поддержки гост-2012) со сторонним несертифицированным модулем с гитхаба (хотя конечно есть и платный сертифицированный вариант, но про него похоже речи не идет раз пошли разговоры про сборку openssl). Задачи для которых придется мастерить именно на основе openssl (несертифицированного!) уж извините крайне ограничены. Например, тоже в своем решении пару-тройку лет назад думал поддержать openssl наряду с cryptoapi, но потом свернул это направление из-за слишком громоздкой и несертифицированной конструкции.
Отредактировано пользователем 8 июня 2020 г. 8:13:06(UTC)
| Причина: Не указана