Что мне нужно знать о XML-сигнатурах, чтобы заставить SAML работать? - PullRequest
17 голосов
/ 21 декабря 2009

На работе у нас есть веб-приложение, которое нам потребуется для взаимодействия с веб-приложением другой компании с помощью единого входа, проверенного SAML. Наши веб-приложения написаны на PHP, и совершенно неважно, какой язык использует другая компания. Тем не менее, мне нужно было написать простой API, в который другая компания могла бы отправлять запросы SOAP с запросами SAML и генерировать ответ SAML. Я писал его с нуля по трем причинам: 1) на самом деле, похоже, не так много вариантов взаимодействия SAML, написанных на PHP, даже если бы я хотел, 2) это ограничивает накладные расходы, связанные с добавлением другого стороннего компонента, и 3) создание вещей с нуля, как правило, дает мне гораздо лучшее понимание и делает меня гораздо более способным адаптировать эту вещь в будущем если нужно.

В любом случае, я довольно новичок в стандартах SAML, SOAP и XML в целом, поэтому я как бы учил себя на ходу. Для наших целей у меня есть почти полный API, за исключением того, что другая компания указала, что наш ответ должен будет иметь цифровую подпись с сертификатом (и полученный нами запрос будет также иметь цифровую подпись). Поэтому я пытался выяснить, как обрабатывать / генерировать подписи XML, но, честно говоря, все это немного сбивает с толку, поскольку спецификации W3C не совсем легкие для чтения.

Раздел 5.4.8 документа Утверждения и протокол для языка разметки безопасности OASIS (SAML) V1.1 (документ, который я отправлял, поскольку другая компания сказала, что они будут использование v1.1) включает в себя пример подписанного ответа, содержащего подписанное утверждение, которое я собираюсь включить сюда для ссылки:

<Response IssueInstant="2003-04-17T00:46:02Z" MajorVersion="1" MinorVersion="1"
 Recipient="www.opensaml.org" ResponseID="_c7055387-af61-4fce-8b98-e2927324b306"
 xmlns="urn:oasis:names:tc:SAML:1.0:protocol"
 xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo>
   <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
   <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
   <ds:Reference URI="#_c7055387-af61-4fce-8b98-e2927324b306">
    <ds:Transforms>
     <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
      <InclusiveNamespaces PrefixList="#default saml samlp ds xsd xsi"
       xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/>
     </ds:Transform>
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
    <ds:DigestValue>TCDVSuG6grhyHbzhQFWFzGrxIPE=</ds:DigestValue>
   </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>x/GyPbzmFEe85pGD3c1aXG4Vspb9V9jGCjwcRCKrtwPS6vdVNCcY5rHaFPYWkf+5EIYcPzx+pX1h43SmwviCqXRjRtMANWbHLhWAptaK1ywS7gFgsD01qjyen3CP+m3Dw6vKhaq1ed10BYyrIzb4KkHO4ahNyBVXbJwqv5pUaE4=</ds:SignatureValue>
  <ds:KeyInfo>
   <ds:X509Data>
    <ds:X509Certificate>MIICyjCCAjOgAwIBAgICAnUwDQYJKoZIhvcNAQEEBQAwgakxCzAJBgNVBAYTA1VT ... 8I3bsbmRAUg4UP9hH6ABVq4KQKMknxu1xQxLhpR1y1GPdiowMNTrEG8cCx3w/w==</ds:X509Certificate>
   </ds:X509Data>
  </ds:KeyInfo>
 </ds:Signature>
 <Status><StatusCode Value="samlp:Success"/></Status>
 <Assertion AssertionID="_a75adf55-01d7-40cc-929f-dbd8372ebdfc"
  IssueInstant="2003-04-17T00:46:02Z" Issuer="www.opensaml.org"
  MajorVersion="1" MinorVersion="1" xmlns="urn:oasis:names:tc:SAML:1.0:assertion"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Conditions NotBefore="2003-04-17T00:46:02Z" NotOnOrAfter="2003-04-17T00:51:02Z">
   <AudienceRestrictionCondition>
    <Audience>http://www.opensaml.org</Audience>
   </AudienceRestrictionCondition>
  </Conditions>
  <AuthenticationStatement AuthenticationInstant="2003-04-17T00:46:00Z"
   AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password">
   <Subject>
    <NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">scott@example.org</NameIdentifier>
    <SubjectConfirmation>
     <ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</ConfirmationMethod>
    </SubjectConfirmation>
   </Subject>
   <SubjectLocality IPAddress="127.0.0.1"/>
  </AuthenticationStatement>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
   <ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
    <ds:Reference URI="#_a75adf55-01d7-40cc-929f-dbd8372ebdfc">
     <ds:Transforms>
      <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
      <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
       <InclusiveNamespaces PrefixList="#default saml samlp ds xsd xsi"
        xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      </ds:Transform>
     </ds:Transforms>
     <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
     <ds:DigestValue>Kclet6XcaOgOWXM4gty6/UNdviI=</ds:DigestValue>
    </ds:Reference>
   </ds:SignedInfo>
   <ds:SignatureValue>hq4zk+ZknjggCQgZm7ea8fI79gJEsRy3E8LHDpYXWQIgZpkJN9CMLG8ENR4Nrw+n7iyzixBvKXX8P53BTCT4VghPBWhFTSt9tHWu/AtJfOTh6qaAsNdeCyG86jmtp3TDMWuL/cBUj2OtBZOQMFn7jQ9YB7k1Iz3RqVL+wNmeWI4=</ds:SignatureValue>
   <ds:KeyInfo>
    <ds:X509Data>
     <ds:X509Certificate>MIICyjCCAjOgAwIBAgICAnUwDQYJKoZIhvcNAQEEBQAwgakxCzAJBgNVBAYTA1VT ... 8I3bsbmRAUg4UP9hH6ABVq4KQKMknxu1xQxLhpR1y1GPdiowMNTrEG8cCx3w/w==</ds:X509Certificate>
    </ds:X509Data>
   </ds:KeyInfo>
  </ds:Signature>
 </Assertion>
</Response>

Так как мне сгенерировать что-то подобное? И если я получу что-то подобное, как мне это проверить? Кроме того, может ли кто-нибудь предложить лишь базовый концептуальный обзор того, что теги <ds:Signature> здесь? Кажется, есть два тега <ds:Signature>, один в основном <Response> и один в <Assertion>, каждый из которых содержит свои собственные <ds:DigestValue>, <ds:SignatureValue> и <ds:X509Certificate> (и каждый отличается). Как они генерируются? Любой свет, который вы можете пролить на это, будет высоко ценится. Учебники или примеры кода будут еще более ценными! Но на данный момент, если вы можете просто привести меня на правильный путь, это все, что я действительно прошу. Сейчас мне все еще кажется большой черный ящик.

Кстати, если это помогает, в другом месте спецификации SAML 1.1 говорится, что реализации SAML должны использовать только метод «Эксклюзивная канонизация» (Excl-C14N) и должны использовать только «конвертированное преобразование». Я все еще не совсем уверен, что это значит.

Ответы [ 3 ]

29 голосов
/ 21 декабря 2009

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

В любом случае, я мало что знаю о SAML, но я знаю о XML и XML-сигнатурах, так что, возможно, я смогу помочь вам, попробовав ответить на ваши вопросы.

Элемент Signature относится к конкретному фрагменту документа XML с цифровой подписью в его дочернем элементе SignedInfo. Дочерний элемент Reference этого (я думаю, что может быть много элементов Reference, которые сцепляются при формировании байтов для подписи, но я уже не помню точно) указывает на содержимое с помощью атрибута URI. Элементы Transform описывают преобразования, выполняемые с указанным контентом перед его хэшированием; вам нужно будет взглянуть на спецификации, чтобы понять, как определяются алгоритмы преобразования. Элемент DigestMethod предоставляет алгоритм хеширования, который применяется к байтам, которые являются результатом этих алгоритмов преобразования (обратите внимание, что одним из них всегда является канонизация, которая преобразует XML в байты), а DigestValue дает результат этого алгоритма дайджеста. .

Фактическая подпись находится в элементе SignatureValue и создается путем применения канонизации элемента CanonicalizationMethod для создания байтов и последующей подписи этих байтов с помощью SignatureMethod. Элемент KeyInfo сообщает вам, как найти ключ для использования.

Канонизация, которая появляется пару раз выше, - это просто способ преобразования XML-документа в байты, чтобы «эквивалентные» XML-документы создавали одинаковую последовательность байтов. Это требуется для цифровой подписи, поскольку алгоритмы работают с байтами, а XML может проходить через ряд посредников, которые, вероятно, нарушат исходные байты, но сохранят эквивалентность. И разные методы канонизации необходимы для разных ситуаций: если элементы извлекаются из документов и помещаются в другие, вам нужна исключительная канонизация, которая удаляет ненужные определения пространства имен, но в других случаях это может работать некорректно, поэтому вместо этого вам нужна инклюзивная канонизация, которая сохраняет все пространства имен в области.

Это всего лишь основы. Существует несколько различных способов создания XML-подписи, и если вы хотите реализовать работающий верификатор, вам необходимо рассмотреть все из них. Поскольку вы новичок в XML в целом, я просто повторю свой совет по использованию того, что уже существует. Реализация спецификации представляет собой интересный опыт обучения, но часто это пустая трата времени, если реализации уже доступны.

Имеется документация W3C о подписи.

2 голосов
/ 21 декабря 2009

В xmlseclibs.php есть пример в SimpleSAML . Для шифрования он использует модуль openssl.

Я бы честно использовал эту библиотеку или мост для java / tomcat, просто потому, что могут возникнуть проблемы с взаимодействием, которые потенциально должны быть отлажены

0 голосов
/ 17 июля 2016
  1. Вы можете взглянуть на эту библиотеку Java, чтобы подписать пример запроса SAML https://github.com/jrowny/java-saml

  2. Для проверки подписи необходимо установить дополнение SAML tracer https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/

  3. Вы можете использовать инструмент https://www.samltool.com/validate_logout_req.php для проверки или подписания запроса https://www.samltool.com/sign_logout_req.php

...