Какая из них является правильной канонизацией XML exclusive?

StackOverflow https://stackoverflow.com/questions/2200988

Вопрос

Я использую xmlсеклибы попытаться подписать документ SOAP, но, похоже, он не канонизирует вещи одинаково в зависимости от того, подписываю я или подтверждаю.

Я приведу вам пример.Это XML, который я пытаюсь подписать:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" MajorVersion="1" MinorVersion="1" IssueInstant="2010-02-04T15:27:43Z" ResponseID="pfxe85313e6-e688-299a-df06-30f55e24f65a">
<samlp:Status>
<samlp:StatusCode Value="samlp:Requester"/>
</samlp:Status>
</samlp:Response>
</soapenv:Body>
</soapenv:Envelope>

Я получил некоторый код, работающий на PHP, чтобы подписать его, используя комбинацию сертификатов открытого ключа и закрытого ключа, и, похоже, это сработало.Это добавило <ds:Signature> элемент со всеми необходимыми вещами, и это выглядело великолепно.Но затем я протестировал его, сразу же попытавшись подтвердить его после подписания, снова с помощью xmlseclibs (и сертификата открытого ключа), но проверка завершилась неудачей.Таким образом, одна и та же библиотека кода выполняет и подписание, и проверку, но по какой-то причине эти два процесса не согласуются.

Я добавил некоторый отладочный код в xmlseclibs, чтобы выяснить, что он делает, и я понял, что причина, по которой ключ подписи, который он выдает, и ключ проверки, который он выдает, отличаются, заключается в том, что он канонизирует вещи по-разному в двух ситуациях.Когда я прикажу ему подписать <samlp:Response> элемент, это каноническая форма, которую он подписывает (я добавил здесь новые строки для удобства чтения):

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" IssueInstant="2010-02-04T15:27:43Z" MajorVersion="1" MinorVersion="1" ResponseID="pfxe85313e6-e688-299a-df06-30f55e24f65a" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<samlp:Status>
<samlp:StatusCode Value="samlp:Requester">
</samlp:StatusCode>
</samlp:Status>
</samlp:Response>

Однако, когда он переходит к проверке подписи, это каноническая форма, которую он вычисляет для проверки (опять же, я добавил здесь новые строки):

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" IssueInstant="2010-02-04T15:27:43Z" MajorVersion="1" MinorVersion="1" ResponseID="pfxe85313e6-e688-299a-df06-30f55e24f65a">
<samlp:Status>
<samlp:StatusCode Value="samlp:Requester">
</samlp:StatusCode>
</samlp:Status>
</samlp:Response>

Итак, как вы можете видеть, в этой версии отсутствует xmlns:saml атрибут из <samlp:Response> элемент, в то время как первый этого не делает.(Обратите внимание, что это отличается от xmlns:samlp атрибут, который включен в оба.) Это довольно явно похоже на ошибку в xmlseclibs, но, тем не менее, я был бы рад исправить ее сам, если бы только знал, какая каноническая форма была правильной.Должен ли этот атрибут быть опущен при исключительной канонизации?Или это должно быть включено?Какая из них является правильной исключительной канонической формой?

Это было полезно?

Решение

Вы неправильно создаете документ DOM и пытаетесь использовать недопустимое дерево в памяти.Либо сериализуйте и используйте сериализованный результат, либо правильно создайте объявления пространства имен в дереве, прежде чем пытаться подписать.Смотрите отчет об ошибке для получения дополнительной информации: http://code.google.com/p/xmlseclibs/issues/detail?id=6

Другие советы

Ни то, ни другое не является правильной канонической формой!

Подписывающий XML содержит объявление пространства имен, которое следует после атрибутов, не относящихся к пространству имен, что нарушает правило порядка документов:

Узлы пространства имен имеют меньшую позицию в порядке документов, чем узлы атрибутов.

В проверочном XML-файле отсутствует saml узел пространства имен полностью.Канонизация не удаляет узлы пространства имен только потому, что нет дочернего содержимого, которое ссылается на них.Он удаляет только избыточные узлы пространства имен (т.е.пространства имен, которые уже действовали на родительском сервере).

Я недостаточно знаю о xmlseclibs, чтобы сказать, почему это происходит, но это определенно неправильно по обоим пунктам.FWIW функция c14n в моем DOM здесь говорит:

<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" IssueInstant="2010-02-04T15:27:43Z" MajorVersion="1" MinorVersion="1" ResponseID="pfxe85313e6-e688-299a-df06-30f55e24f65a">
<samlp:Status>
<samlp:StatusCode Value="samlp:Requester"></samlp:StatusCode>
</samlp:Status>
</samlp:Response>

eta:Я просто посмотрел на xmlseclibs.php в SVN, и это нелегко исправить, поскольку его текущий подход в корне ошибочен.Он пытается создать “канонизированный” DOM, а затем сериализует его с помощью простого старого saveXML().Поскольку существуют правила сериализации C14N о порядке атрибутов, и символы экранируют это saveXML не обещает следовать, это никоим образом не может сработать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top