PHP и SOAP Message Security

Очередной случай из жизни натолкнул меня на мысль расписать, как из PHP создать подписанный по стандарту SOAP Message Security SOAP-запрос по SSL-соединению. Насколько я понимаю, стандарт этот не единственный, но используется достаточно широко и базируется на различных XML-стандартах W3C.

Сама суть механизма подписи хорошо описана в этой статье, из которой и я почерпнул для себя несколько полезных моментов, на которых возник ступор поначалу. Но предлагаемый мной вариант имеет одно важное дополнение: он добавляет в SOAP-сообщение ещё и информацию о сертификате, с помощью которого была сделана подпись. Кстати, меня удивила логика одной системы, для которой это делалось (кстати, написанной на Microsoft’овских компонентах): помимо сертификата в SSL-соединении они ещё проверяли сертификат и в самом запросе, хотя могли бы и воспользоваться данными HTTPS и тем самым получить ещё дополнительную проверку того, что соединение открыто тем самым агентом, который подписывал запрос.

Основным моментом в подписи является то, что собираются хэши (дайджесты) узлов с данными, которые будут подписаны (при этом узлы приводятся в канонический вид с помощью утилиты xmllint из комплекта libxml2). После чего собранные внутри одной «обёртки» дайджесты подписываются ключом сертификата, тем самым гарантируя, что если подпись верна, то данные в этих узлах не были изменены во время передачи запроса.

Класс так-же переписывает механизм HTTP-запроса к удалённому серверу, т.к. даже с помощью stream_context PHP не позволяет использовать совместно с SOAP сертификаты в формате PKCS12. В итоге используется HTTPRequest, результат которого уже транслируется далее в обработку.

Leave a Reply