works validate support samlrequest idp how php xml digital-signature saml xml-signature

php - validate - ¿Qué necesito saber sobre las firmas XML para que SAML funcione?



samlrequest (3)

  1. Puede consultar esta biblioteca Java para firmar el ejemplo de solicitud SAML https://github.com/jrowny/java-saml

  2. Para validar la firma, debe instalar el complemento SAML Tracer https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/

  3. Puede usar la herramienta https://www.samltool.com/validate_logout_req.php para validar o firmar la solicitud https://www.samltool.com/sign_logout_req.php

En el trabajo tenemos una aplicación web que necesitaremos para interactuar con la aplicación web de otra compañía utilizando el inicio de sesión único validado por SAML. Nuestras aplicaciones web están escritas en PHP, y obviamente es irrelevante qué opción de idioma está usando la otra compañía. No obstante, he necesitado escribir una API simple a la que esta otra empresa pueda enviar solicitudes SOAP con solicitudes SAML y generar una respuesta SAML. Lo he estado escribiendo desde cero por tres razones: 1) realmente no parece haber muchas opciones para las interacciones SAML escritas en PHP incluso si quisiera una, 2) limita la sobrecarga que implicaría agregar otro tercero -el componente de la parte, y 3) crear cosas desde cero generalmente me deja con una comprensión significativamente mejor y me hace mucho más capaz de adaptarla en el futuro si es necesario.

De todos modos, soy bastante nuevo en los estándares SAML, SOAP y XML en general, así que me he estado enseñando a medida que avanzo. Tengo la API bastante completa para nuestros propósitos, con la única excepción de que la otra compañía ha especificado que nuestra respuesta deberá estar firmada digitalmente con un certificado (y la solicitud que recibimos también estará firmada digitalmente). Así que he estado tratando de averiguar cómo procesar / generar las firmas XML, pero honestamente, todo es un poco confuso, ya que las especificaciones de W3C no son exactamente claras.

La sección 5.4.8 de las aserciones y el protocolo para el documento OASIS Security Markup Language (SAML) V1.1 (el documento que he estado publicando, ya que la otra compañía dijo que van a usar v1.1) incluye un ejemplo de una respuesta firmada que contiene una aserción firmada, que voy a incluir aquí como 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">[email protected]</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 genero algo como esto? Y si recibo algo como esto, ¿cómo lo validaré? Además, ¿alguien puede ofrecer solo una descripción conceptual básica de lo que están aquí las etiquetas <ds:Signature> ? Parece que hay dos etiquetas <ds:Signature> , una en la principal <Response> y otra en la <Assertion> , cada una con su propio <ds:DigestValue> , <ds:SignatureValue> y <ds:X509Certificate> ( y cada uno distinto). ¿Cómo se generan estos? Cualquier luz que puedas arrojar sobre esto será muy apreciada. Tutoriales o ejemplos de código serían aún más apreciados! Pero en este punto, si puedes conseguirme en el camino correcto, eso es todo lo que realmente estoy pidiendo. En este momento, todo sigue pareciéndome una gran caja negra para mí.

Por cierto, si esto ayuda, dice en otra parte de la especificación SAML 1.1 que las implementaciones de SAML deben usar solo el método de "Canonización exclusiva" (Excl-C14N) y deben usar solo la "transformación envuelta". Todavía no estoy completamente seguro de lo que eso significa.


El procesamiento de firmas XML no es realmente demasiado difícil, si está muy familiarizado con XML, pero hay muchos detalles que tienen que ser absolutamente correctos o las cosas no funcionan, así que probablemente no intente escribir mi propia implementación en este situación (la implementé parcialmente una vez, pero fue para un propósito diferente y especial, y de todos modos no fue una implementación completa).

De todos modos, no sé mucho sobre SAML, pero sí conozco sobre firmas XML y XML, así que tal vez pueda ayudarlo a intentar responder sus preguntas.

Un elemento de Signature se refiere a una parte específica de un documento XML que se ha firmado digitalmente, en su elemento secundario SignedInfo . El elemento secundario de Reference de eso (creo que puede haber muchos elementos de Reference que se concatenan cuando se forman los bytes que deben firmarse, pero no recuerdo con seguridad) apunta al contenido a través del atributo URI . Los elementos de transformación describen las transformaciones realizadas en el contenido referido antes de incluirlo; tendrá que mirar las especificaciones para averiguar cómo se definen los algoritmos de transformación. El elemento DigestMethod proporciona 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 la DigestValue que convierte XML en bytes), y DigestValue proporciona el resultado de ese algoritmo de resumen.

La firma real está en el elemento SignatureValue y se produce al aplicar la CanonicalizationMethod elemento CanonicalizationMethod para producir los bytes y luego firmar estos bytes con SignatureMethod . El elemento KeyInfo le dice cómo encontrar la clave a usar.

La canonización, que aparece un par de veces arriba, es simplemente una forma de convertir un documento XML en bytes para que los documentos XML "equivalentes" produzcan la misma secuencia de bytes. Esto se requiere en una firma digital porque los algoritmos funcionan en bytes y XML puede pasar a través de una serie de intermediarios que probablemente interrumpirán los bytes originales pero conservarán la equivalencia. Y se necesitan diferentes métodos de canonicalización para diferentes situaciones: si los elementos se extraen de documentos y se colocan en otros, necesita una canonicalización exclusiva que elimine las definiciones de espacio de nombres innecesarias, pero en otros casos puede que no funcione correctamente, por lo que necesita una canonicalización inclusiva. conserva todos los espacios de nombres en el ámbito.

Esto es sólo lo básico. Hay una serie de opciones diferentes sobre cómo producir una firma XML, y si desea implementar un verificador que funcione, debe considerarlos todos. Como usted es nuevo en XML en general, solo repetiré mi consejo de usar 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.

Existe la documentation del W3C sobre firmas.


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

Honestamente usaría esa lib o bridge para java / tomcat, solo porque podrían surgir problemas de interoperabilidad que posiblemente deban ser depurados,