sso certificate signature saml

certificate - sso - SAML: ¿Por qué el certificado está dentro de la Firma?



php saml (4)

Tengo que implementar SSO con SAML para el sitio web de mi empresa (como parte dependiente). Una parte esencial del curso es la verificación de la firma. Aquí está la parte de la firma de una SAML de muestra de nuestra empresa asociada (parte afirmativa):

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/> <ds:Reference URI="#_2152811999472b94a0e9644dbc932cc3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:Transforms xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ec:InclusiveNamespaces PrefixList="ds saml samlp xs" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/> </ds:Transform> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/> <ds:DigestValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">bW1Os7+WykqRt5h0mdv9o3ZF0JI=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> cgrAN4T/UmobhrkkTi3miiRfbo0Z7aakSZjXuTWlZlu9jDptxPNbOFw8ZbYKZYyuW544wQqgqpnG gr5GBWILSngURjf2N45/GDv7HMrv/NRMsRMrgVfFsKbcAovQdLAs24O0Q9CH5UdADai1QtDro3jx nl4x7HaWIo9F8Gp/H1c= </ds:SignatureValue> <ds:KeyInfo> <ds:X509Data> <ds:X509Certificate>MIIElzCCA3+gAwIBAgIQNT2i6HKJtCXFUFRB8qYsZjANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQG EwJGUjEOMAwGA1UEBxMFUGFyaXMxDDAKBgNVBAoTA3BzYTEgMB4GA1UECxMXY2VydGlmaWNhdGUg YXV0aG9yaXRpZXMxKDAmBgNVBAMTH0FDIFBTQSBQZXVnZW90IENpdHJvZW4gUHJvZ3JhbXMwHhcN MDkwODE5MDcxNTE4WhcNMTEwODE5MDcxNTE5WjCBhjELMAkGA1UEBhMCZnIxHzAdBgkqhkiG9w0B CQEWEHBhc3NleHRAbXBzYS5jb20xGDAWBgoJkiaJk/IsZAEBEwhtZGVtb2IwMDEMMAoGA1UEChMD cHNhMREwDwYDVQQLEwhwcm9ncmFtczEbMBkGA1UEAxMSVGVzdCAtIFBBU1NFWFQgREVWMIGfMA0G CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuY1nrepgACvDSTLWk5A1cFOJSwDbl6CWfYp3cNYR0K3YV e07MDZn+Rv4jo3SusHVFds+mzKX2f8AeZjkA3Me/0yiS9UpS9LQZu9mnhFlZRhmUlDDoIZxovLXN aOv/YHmPeTQMQmJZu5TjqraUq7La1c187AoJuNfpxt227N1vOQIDAQABo4IBkTCCAY0wDgYDVR0P AQH/BAQDAgWgMB8GA1UdIwQYMBaAFLceWtTfVeRuVCTDQWkmwO4U01X/MAwGA1UdEwEB/wQCMAAw gbYGA1UdIASBrjCBqzCBqAYKKoF6ARfOEAEBBDCBmTBBBggrBgEFBQcCARY1aHR0cDovL3JldW5p cy5pbmV0cHNhLmNvbS9hdXRvcml0ZS9QQy1BQy1Qcm9ncmFtcy5wZGYwVAYIKwYBBQUHAgIwSDAK FgNwc2EwAwIBARo6UG9saXRpcXVlIGRlIENlcnRpZmljYXRpb24gQUMgUFNBIFBldWdlb3QgQ2l0 cm9lbiBQcm9ncmFtczBcBgNVHR8EVTBTMFGgT6BNhktodHRwOi8vaW5mb2NlcnQucHNhLXBldWdl b3QtY2l0cm9lbi5jb20vQUMtUFNBLVBldWdlb3QtQ2l0cm9lbi1Qcm9ncmFtcy5jcmwwHQYDVR0l BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBYGA1UdDgQPBA1BVVRPX0dFTkVSQVRFMA0GCSqGSIb3 DQEBBQUAA4IBAQCvRtP6bFkOUEHcqc6yUX0Q1Gk2WaAcx4ziUB0tw2GR9I0276JRJR0EGuJ/N6Fn 3FhLQrSPmS97Xvc9XmiI66fQUdg64g9YqBecdiQlUkR20VLgI6Nq8pldQlWjU2iYlkP15U7VF4Qr 0Pb2QiIljZUCKdv3qdED2Ri33za46LfykrlwZB0uhTVUxI/AEtjkKVFaZaqanJg+vJyZI5b30z7g Ff8L3ht4Z7SFKdmY3IQSGzElIAAUfduzTJX0cwnGSU9D4BJu1BS8hWnYPwhk+nBJ7OFhXdwYQFWq fhpBLq+ciJti9OMhcdCSIi0PbrOqzqtX7hZUQOvfShhCTJnl5TJJ</ds:X509Certificate> </ds:X509Data> </ds:KeyInfo> </ds:Signature>

Lo que simplemente no entiendo es, ¿por qué el certificado está dentro de la firma?

Quiero decir, generalmente obtengo un certificado de la compañía de una manera segura, así que sé que el certificado es de ellos. Y cuando la verificación de la firma tiene éxito, sé que nuestra empresa asociada lo ha firmado.

Pero cuando el certificado está dentro de la firma de SAML-Response, ¡cualquiera podría haberlo enviado! Lo único que sé es que la respuesta no ha sido falsificada. Pero el punto es que no tengo idea de quién envió el SAML.

¿Alguien puede explicarme cómo funciona eso?


El motivo por el que se especifica la clave es que los metadatos para el proveedor de identidad pueden especificar varias claves de firma, y ​​puede especificar la clave que se usará incluyéndolo con la firma. SAML 2.0 requiere que si la clave no está especificada con la Assertion , entonces se puede inferir por contexto (de los Metadatos para la parte que hace la afirmación).

Por ejemplo, puede tener esto en sus Metadatos para la parte que afirma:

<KeyDescriptor> <ds:KeyInfo> <ds:X509Data> <ds:X509Certificate> BQUAMCMxITAfBgNVBAMTGGlkcDEudGFuZ29oZWFsdGhkZW1vLmNvbTAeFw0xMzA1 ...snip... ttHq2Wi5J7img1M2zo28hH5DK78S+XerfXHK2HEZYZs= </ds:X509Certificate> </ds:X509Data> <ds:X509Data> <ds:X509Certificate> H24a88h7zlq+pnAxQm0CAwEAAaN3MHUwVAYDVR0RBE0wS4IYaWRwMS50YW5nb2hl ...snip... mg1M2zo28hH5DK78= </ds:X509Certificate> </ds:X509Data> </ds:KeyInfo> </KeyDescriptor>

Cada elemento XML que se firma puede especificar qué clave se utiliza para la firma. Sin embargo, con el caso de SAML 2.0, esa clave de firma debe (por ejemplo) coincidir con una que esté definida en los Metadatos para la parte que genera la firma. Si la clave suministrada con la firma no es de confianza (no se especifica en Metadata en este caso), entonces el sistema SAML debe generar un error al validar la firma.


La parte pública del certificado de firma está en el mensaje SAML. Esto se usa para verificar la firma del token y, por supuesto, para permitir que los receptores digan quién emitió el token y lo trate en consecuencia.

El hecho de que esté allí es parte de las especificaciones de firma digital XML, en realidad no es nada específico de SAML. Sin el certificado, ¿cómo podrías saber de dónde vino el token y cómo podrías validarlo?

XmlDSig especifica otros métodos, puede identificar la clave de firma por un asunto, número de serie, hash, etc., pero esto supone que la parte receptora tiene el certificado público. Para SAML, este puede no ser el caso, de ahí la incorporación de la parte pública del certificado X509.


Las respuestas de SAML vienen con una firma y una clave pública para esa firma.

Puede usar la clave pública para verificar que el contenido de la respuesta de SAML coincida con la clave; en otras palabras, que la respuesta proviene definitivamente de alguien que tiene la clave privada correspondiente a la clave pública en el mensaje, y la respuesta no ha sido manipulado.

No sé con qué tecnología estás trabajando, pero en .Net puedes verificarlo así:

// load a new XML document var assertion = new XmlDocument { PreserveWhitespace = true }; assertion.LoadXml("The SAML XML that you were sent"); // use a namespace manager to avoid the worst of xpaths var ns = new XmlNamespaceManager(assertion.NameTable); ns.AddNamespace("samlp", @"urn:oasis:names:tc:SAML:2.0:protocol"); ns.AddNamespace("asrt", @"urn:oasis:names:tc:SAML:2.0:assertion"); ns.AddNamespace("dsig", @"http://www.w3.org/2000/09/xmldsig#"); // get nodes down to the signature var responseNode = assertion.SelectSingleNode("/samlp:Response", ns); var assertionNode = responseNode.SelectSingleNode("asrt:Assertion", ns); var signNode = assertionNode.SelectSingleNode("dsig:Signature", ns); // load the XML signature var signedXml = new SignedXml(assertion.DocumentElement); signedXml.LoadXml(signNode as XmlElement); // get the certificate, basically: // signedXml.KeyInfo[0].Certificates[0] // ...but with added casting var certificate = GetFirstX509Certificate(signedXml); // check the key and signature match bool isSigned = signedXml.CheckSignature(certificate, true);

Eso solo comprueba que el mensaje es de quién dice que es. Necesita una verificación adicional de que el mensaje proviene de alguien en quien confía, y este cheque es más lento; debe incluir la revocación y es posible que deba verificar toda una cadena de certificados.

Normalmente, esta será una lista de claves públicas de las que aceptaría respuestas SAML.

Luego, puede verificar que este mensaje no haya sido manipulado, y que sea de alguien en quien confía, por lo que puede autorizar los detalles del usuario proporcionados en los atributos de SAML suministrados.

Ya podría tener la clave pública, lo que significa que la firma no debería volver a incluir la clave pública, pero también podría tener múltiples posibles remitentes conocidos, o incluso una cadena de remitentes conocidos.

Por ejemplo, puede tener dos proveedores de confianza: en cualquier caso, compruebe que el mensaje no haya sido alterado antes de verificar si confía en cualquiera de los proveedores. Si la clave no está en la firma, las afirmaciones pueden ser un poco más pequeñas, pero ahora debe saber de antemano de qué proveedor de identidad proviene la afirmación.

Entonces, realmente, hay dos razones principales por las que la clave pública está en la firma:

  1. La verificación de falsificación es más rápida que la verificación de identidad y puede aislarse si se conoce la clave pública.
  2. Las identidades múltiples son mucho más fáciles de admitir si la clave está en la aserción.