краткий ответ: в исходный вопрос добавьте doc.normalizeDocument();
в начале applySignature
, поэтому перед добавлением подписи.
больше информации:
Я знаю, что это старый вопрос, но у меня была похожая проблема, которая не была решена ни одним из ответов.
На самом деле, я думаю, что один из ответов неправильный, он говорит, что проблема в проверке. Тем не менее, я считаю, что это в подписании! Я надеюсь, что использование моего опыта и решений поможет кому-то с подобной проблемой.
Я генерировал документ XML, а затем подписывал его. Я пытался подписать с Apache Santuario. Когда это не сработало, я переключился на javax.xml.crypto.dsig.
Оба эти метода генерировали XML-документы, которые были неправильно подписаны, когда я проверял их с помощью Santuario и внешних инструментов!
Первый пример подписанного XML, который я пытался сгенерировать:
<signed-envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="somenamespace" xsi:schemaLocation="someshemelocation">
<object xml:id="object0">
...
</object>
<signatures>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
...
<SignedInfo>
<Reference URI="#object0">
...
</SignedInfo>
</Signature>
</signatures>
</signed-envelope>
Пространства имен signed-envelope
имеют решающее значение! Все отлично работало без пространств имен. Но когда я добавил необходимое пространство имен в signed-envelope
, подпись сгенерировала файл XML, который не удалось проверить. Также не с помощью внешнего инструмента (что означает, что подпись не удалась, а не проверка)!
Santuario предлагает отличные результаты отладки с помощью log4j. Эти выходные данные показали, что при проверке следующее пространство имен было добавлено к <object>
и <SignedInfo>
:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Это правильный способ проверки! Один из ответов здесь предполагает, что это не правильно, и пытается это исправить, но на самом деле это правильно. Проблема здесь не в проверке, а в подписании!
Проблема в том, что Santuario показал, что это пространство имен НЕ было добавлено при подписании документа! Это заставило меня поверить, что что-то не так с Document
объектом, который я сгенерировал.
Мой XML-документ был сгенерирован с пространством имен, добавленным в корневой элемент, например:
rootElement.setAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "xsi:noNamespaceSchemaLocation", "some_namespace");
После долгих поисков я обнаружил, что doc.normalizeDocument()
решил похожую проблему. Я попробовал, и все работает!
Я понятия не имею, почему doc.normalizeDocument()
заставляет все работать, но теперь я могу правильно подписать и Apache Santuario, и javax.xml.crypto.dsig. Таким образом, они оба нуждаются в этом, чтобы подписать правильно.