Что мне нужно знать о XML-подписях, чтобы заставить SAML работать?

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

Вопрос

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

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

Раздел 5.4.8 настоящего Утверждения и протокол для языка разметки безопасности OASIS (SAML) версии 1 документ (документ, который я отправлял, поскольку другая компания заявила, что они будут использовать версию 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 должны использовать только метод "Эксклюзивной канонизации" (кроме C14N) и должны использовать только "обернутое преобразование".Я все еще не совсем уверен, что это значит.

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

Решение

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

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

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

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

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

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

Есть W3C's Документация о подписях.

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

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

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

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

  2. Для проверки подписи вам необходимо установить надстройку трассировщика SAML. 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

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