Pregunta

En el trabajo tenemos una aplicación web que vamos a necesitar para interactuar con aplicación web de otra empresa que utiliza inicio de sesión único validado por SAML. Nuestras aplicaciones web están escritas en PHP, y es obviamente irrelevante qué idioma elegir la otra compañía está utilizando. No obstante, he necesitado para escribir una API simple que esta otra compañía puede enviar peticiones SOAP a las solicitudes SAML, y generar una respuesta de vuelta SAML. He estado escribiendo desde cero por tres razones: 1) que hay en realidad parecían no estar muchas opciones para las interacciones SAML escritas en PHP aunque quisiera uno, 2) limita la sobrecarga que estaría involucrado con la adición de otro componente de terceros, y 3) crear cosas desde cero por lo general me deja con una significativamente mejor comprensión y me hace mucho más capaz de adaptarse lo en el futuro si es necesario.

De todas formas, soy bastante nuevo en SAML, SOAP, XML y las normas en general, así que he estado enseñando a mí mismo tipo de medida que avanzo. Tengo la API más o menos completa para nuestros propósitos, con la única excepción de que la otra compañía ha especificado que se requiere nuestra respuesta debe ser firmado digitalmente con un certificado (y la solicitud que recibimos será similar, sea firmado digitalmente). Así que he estado tratando de encontrar la manera de procesar / generar las firmas XML, pero la verdad es que todo es un poco confuso ya que las especificaciones de W3C no son exactamente la lectura luz.

Sección 5.4.8 de la las afirmaciones y Protocolo para la Seguridad OASIS Markup Language (SAML) documento v1.1 (el documento que he estado yendo fuera, como la otra empresa dijeron que usarán v1.1) incluye un ejemplo de una respuesta firmada que contiene una afirmación firmado, que voy a incluir aquí para referencia:

<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>

Entonces, ¿cómo puedo generar algo como esto? Y si recibo algo así, ¿cómo puedo validarlo? Además, cualquier persona puede ofrecer sólo una visión conceptual básico de lo que las etiquetas <ds:Signature> están aquí? Parece que hay dos etiquetas <ds:Signature>, uno en el <Response> principal y uno en la <Assertion>, cada uno con su propio <ds:DigestValue>, <ds:SignatureValue> y <ds:X509Certificate> (y cada uno distinto). ¿Cómo se generan éstos? Cualquier luz que puede arrojar sobre este será muy apreciada. Tutoriales o ejemplos de código serían aún más apreciados! Pero en este punto, si sólo me puede conseguir en el camino correcto, eso es todo lo que realmente estoy pidiendo. En este momento todo todavía parece un cuadro negro grande para mí.

Por cierto, si esto ayuda, se dice en la especificación 1.1 de SAML que las implementaciones de SAML deben utilizar el método "exclusivo canónicos" (exc-C14N) y deben utilizar en otros lugares del "envolvió transformar" solamente. Todavía no estoy completamente seguro de lo que eso significa.

¿Fue útil?

Solución

Procesamiento de firmas XML no es realmente muy difícil, si estás muy familiarizado con XML, pero hay una gran cantidad de detalles que tienen que ser absolutamente correcto o las cosas no funcionan, así que probablemente no trate de escribir mi propia aplicación en esta situación (I puso en práctica parcialmente una vez, pero que era para un propósito diferente y especial, y de todos modos no era una implementación completa).

De todos modos, no sé mucho acerca de SAML, pero lo que sé acerca de XML y XML Firmas, por lo que tal vez pueda conseguir que una parte del camino, tratando de responder a sus preguntas.

Un elemento Signature se refiere a una parte específica de un documento XML que ha sido firmado digitalmente, en su elemento SignedInfo niño. El elemento Reference niño de esa (creo que puede haber muchos elementos que se interponen Reference concatenada cuando se forma la bytes para ser firmado, pero no lo recuerdo con certeza más) puntos a los contenidos mediante el atributo URI. Los elementos Transform describen transformaciones realizadas en el referido a contenido antes de hashing ella; tendrá que mirar las especificaciones de averiguar cómo se definen los algoritmos de transformación. El elemento DigestMethod da el algoritmo hash para aplicar a los bytes que son el resultado de estos algoritmos de transformación (tenga en cuenta que uno de ellos es siempre de categorización que convierte XML en bytes), y el DigestValue da el resultado de que el algoritmo de digerir.

La firma real es en el elemento SignatureValue, y se produce mediante la aplicación de canonicalización del elemento CanonicalizationMethod para producir los bytes y luego la firma de estos bytes con el SignatureMethod. El elemento KeyInfo te dice cómo encontrar la clave para su uso.

canónicos, que aparece un par de veces antes, es simplemente una manera de convertir un documento XML en bytes para que "equivalentes" documentos XML producen la misma secuencia de bytes. Esto es necesario en una firma digital, porque los algoritmos trabajan en bytes y XML puede pasar a través de una serie de intermediarios que probablemente contribuyen a perturbar los bytes originales, pero retendrán la equivalencia. Y se necesitan diferentes métodos canónicos para diferentes situaciones: si los elementos se extraen de los documentos y se colocan en los demás, es necesario Canonicalización exclusivo que despoja de las definiciones de espacio de nombres que no sean necesarios, pero en otros casos que no funcione correctamente, por lo que necesita Canonicalización incluido en su lugar, el cual preserva espacios de nombres todo en el estudio.

Esto es sólo lo básico. Hay un número de diferentes opciones en la forma de producir una firma XML, y si se desea implementar un verificador de trabajo, debe tener en cuenta todos ellos. Dado que usted es nuevo en XML, en general, sólo voy a repetir mi consejo de utilizar algo que ya existe. Es una experiencia de aprendizaje interesante implementar una especificación, pero a menudo es una pérdida de tiempo si las implementaciones ya están disponibles.

Hay documentación acerca de las firmas.

Otros consejos

Hay un ejemplo en xmlseclibs.php en SimpleSAML . Se basa en el módulo OpenSSL para hacer el cripto.

Me gustaría utilizar honestamente que lib o puente para Java / Tomcat, sólo por cuestiones de interoperabilidad podrían prevenir que tendrían que ser depurado, potencialmente,

  1. Puede echar un vistazo a este lib Java para firmar la petición SAML ejemplo https: // github.com/jrowny/java-saml

  2. Para validar la firma necesita instalar SAML trazador complemento https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/

  3. Puede utilizar la herramienta https://www.samltool.com/validate_logout_req.php a vaalidate o firmar la solicitud https://www.samltool.com/sign_logout_req.php

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top