SAML: Perché il certificato è contenuto nella firma?


103

Devo implementare il servizio SSO con SAML per il sito Web della mia azienda (come relying party). Una parte essenziale fuori rotta è la verifica della firma. Ecco la parte della firma di un esempio di SAML della nostra azienda partner (asserting party):

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

Quello che non capisco è, perché il certificato è all'interno della firma?

Voglio dire, di solito ottengo un certificato dall'azienda in modo sicuro, quindi so che il certificato proviene da loro. E quando la verifica della firma ha esito positivo, so che la nostra azienda partner l'ha firmata.

Ma quando il certificato si trova all'interno della firma della risposta SAML, chiunque avrebbe potuto inviarlo! L'unica cosa che so è che la risposta non è stata falsificata. Ma il punto è che non ho idea di chi abbia inviato il SAML.

Qualcuno può spiegarmi come funziona?

Risposte:


66

Le risposte SAML vengono fornite con una firma e una chiave pubblica per quella firma.

Puoi utilizzare la chiave pubblica per verificare che il contenuto della risposta SAML corrisponda alla chiave, in altre parole, quella risposta proviene sicuramente da qualcuno che ha la chiave privata corrispondente alla chiave pubblica nel messaggio e la risposta non è stata manomesso.

Non so con quale tecnologia stai lavorando, ma in .Net puoi verificarlo in questo modo:

// 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);

Questo controlla solo che il messaggio provenga da chi dice di essere. Hai bisogno di un ulteriore controllo che il messaggio provenga da qualcuno di cui ti fidi e questo controllo è più lento: deve includere la revoca e potrebbe essere necessario verificare un'intera catena di certificati.

Normalmente questo sarà un elenco di chiavi pubbliche da cui accetteresti le risposte SAML.

Quindi puoi verificare che questo messaggio non sia stato manomesso e provenga da qualcuno di cui ti fidi, in modo da poter autorizzare i dettagli dell'utente forniti negli attributi SAML forniti.

si potrebbe già avere la chiave pubblica, il che significa che la firma non dovrebbe aver bisogno di includere di nuovo la chiave pubblica, ma si potrebbe anche avere più mittenti conosciuti possibili, o anche una catena di mittenti conosciuti.

Ad esempio, potresti avere due provider affidabili: in entrambi i casi controlli che il messaggio non sia stato manomesso prima di verificare se ti fidi di entrambi i provider. Se la chiave non è nella firma, le asserzioni possono essere un po 'più piccole, ma ora devi sapere in anticipo da quale provider di identità proviene l'asserzione.

Quindi, in realtà, ci sono due ragioni principali per cui la chiave pubblica è nella firma:

  1. Il controllo delle manomissioni è più veloce del controllo dell'identità e può essere isolato se la chiave pubblica è nota.
  2. Le identità multiple sono molto più facili da supportare se la chiave è nell'asserzione.

2
@svlada, l'asserzione SAML non necessita della propria crittografia, poiché il testo stesso può essere inviato tramite SSL: l'intera sessione utente deve essere HTTPS. Dato che è sufficiente verificare che il mittente conosciuto e di fiducia abbia firmato l'asserzione e che non sia stata manomessa.
Keith

5
@svlada nessuna autenticazione basata su HTTP (di alcun tipo) dovrebbe mai essere eseguita senza SSL. La crittografia del certificato impedirà a un uomo al centro (MitM) di leggerlo, ma non gli impedirà di riutilizzarlo in modo simile a un attacco MitM basato su cookie.
Keith

8
Le risposte SAML non richiedono l'inclusione della chiave pubblica per quella firma. La sezione 5.4.5 delle specifiche SAML2 afferma "La firma XML definisce l'utilizzo dell'elemento <ds: KeyInfo>. SAML non richiede l'uso di <ds: KeyInfo>, né impone alcuna restrizione sul suo utilizzo. Pertanto, <ds : KeyInfo> POTREBBE essere assente. " Puoi verificare la firma se la chiave pubblica ti è stata fornita con altri mezzi, ad esempio archiviata nell'archivio certificati locale prima di implementare il consumer SAML.
Sam Rueby

2
@ Sam.Rueby ah, lo correggerò. Ogni implementazione che ho visto ha incluso la chiave.
Keith

5
@ Jez questo intero protocollo è confuso come l'inferno. Fondamentalmente l'asserzione è autonoma: puoi verificare che non sia stata manomessa da quando la chiave privata l'ha firmata. Puoi farlo senza avere quella chiave pubblica da solo (quindi so che questa affermazione è arrivata da Dave e che nessuno l'ha manomessa da quando Dave l'ha firmata, ma potrei non avere idea di chi sia Dave o se posso fidarmi di lui). Quindi, dopo aver verificato ciò, posso controllare che la chiave pubblica sia una di cui mi fido. Penso che ciò sia dovuto al fatto che potrebbe esserci un ritardo su quel controllo finale (mentre vado a chiedere dell'ufficio se qualcuno conosce Dave)
Keith

41

Il motivo per cui viene specificata la chiave è che i metadati per il provider di identità possono specificare più chiavi di firma ed è possibile specificare la chiave da utilizzare includendola con la firma. SAML 2.0 richiede che se la chiave non è specificata con l'estensioneAssertion , allora può essere dedotta dal contesto (dai metadati per la parte che asserisce).

Ad esempio, potresti avere questo nei tuoi metadati per la parte asserente:

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

Ogni elemento XML firmato può specificare quale chiave viene utilizzata per la firma. Tuttavia, nel caso di SAML 2.0, quella chiave di firma deve (ad esempio) corrispondere a quella definita nei metadati per la parte che genera la firma. Se la chiave fornita con la firma non è affidabile (in questo caso non specificato nei metadati), il sistema SAML deve generare un errore durante la convalida della firma.


9
Penso che questo sia un punto importante, che il certificato nella risposta deve corrispondere al certificato nei metadati. Altrimenti, potrei firmare la risposta con qualsiasi certificato volessi e inviare la sua chiave pubblica per la verifica.
dana

5
Penso che questa sia la risposta migliore, mi sembra che agli altri manchi il punto che confrontare il messaggio con la chiave dichiarata nel messaggio stesso non ti dà alcuna sicurezza ... Devi comunque controllare la chiave nel messaggio è giusto! (in questo caso, devi assicurarti che sia contenuto in metadati affidabili).
rchampourlier

3
Completamente d'accordo con i commenti di cui sopra: il certificato passato nel messaggio è inutile di per sé perché l'intero punto della firma è verificare che il messaggio sia affidabile. Se il messaggio non è affidabile, non lo sono nemmeno i certificati in bundle.
Jez

@jbindel - grazie! Ho una nuova domanda, se possibile: questo certificato SAML deve corrispondere al certificato fisico corrente o viene utilizzato solo per ottenere una corrispondenza dei metadati? Lo chiedo perché sono preoccupato per l'impatto operativo di un IdP che rielabora il loro certificato - a quel punto presumibilmente non è più sincronizzato con la chiave dei metadati. Se i 2 sono in parità, allora sono preoccupato. l'impatto operativo cioè. che fino a quando sia l'SP che l'IdP non avranno aggiornato manualmente la chiave SAML2, tutto il SSO fallirà e il conseguente impatto sugli utenti SSO se comunicazioni tecniche imperfette. (scusa se domanda stupida)
Pancho

I metadati dell'SP devono includere il certificato, ma i metadati dell'SP possono specificare sia il vecchio che il nuovo certificato IdP. Se l'IdP sta aggiornando il proprio certificato, questo può essere aggiunto ai metadati dell'SP. Una volta che l'IdP dovrebbe essere fatto utilizzando il vecchio certificato, è possibile rimuoverlo dai metadati dell'SP. Questo risponde a quello che chiedi? So che funziona perfettamente su Shibboleth SP. Il file di metadati dell'SP deve contenere solo <KeyDescriptor use="signing">elementi per i certificati IdP che saranno accettati dall'SP.
jbindel

8

La parte pubblica del certificato di firma si trova nel messaggio SAML. Questo viene utilizzato per controllare la firma del token stesso e, naturalmente, per consentire ai destinatari di dire chi ha emesso il token e trattarlo di conseguenza.

Il fatto che sia presente fa parte delle specifiche della firma digitale XML, non è realmente qualcosa di specifico SAML. Senza il certificato come potresti sapere da dove proviene il token e come potresti convalidarlo?

XmlDSig specifica altri metodi, è possibile identificare la chiave di firma da un oggetto, numero di serie, hash ecc., Ma ciò presuppone che la parte ricevente abbia il certificato pubblico. Per SAML questo potrebbe non essere il caso, quindi l'incorporamento della parte pubblica del certificato X509.


1
"Senza il certificato come potresti sapere da dove proviene il token e come potresti convalidarlo?" - di cosa stai parlando? Per considerare attendibile una firma in un messaggio SAML, devi già disporre di un elenco di certificati pubblici attendibili. È possibile utilizzare l' Issuerelemento e archiviare il certificato dell'emittente rispetto a quello e scegliere quel certificato in base al quale controllare la firma per questo messaggio.
Jez

2
Non è affatto vero Jez. Puoi fidarti di un emittente di certificati, come una CA, senza doverti fidare dei singoli certificati che emette e senza dover conservare copie locali di ogni certificato.
Blowdart

3
blowdart significa che ti stai fidando del token saml firmato da qualsiasi altro certificato valido rilasciato da CA. Non è impossibile acquistarne uno! Per assicurarti che il tuo token provenga dalla fonte corretta, come menzionato da @Jez, dovresti già avere un elenco di certificati pubblici affidabili.
Dom

2
@Sun, non corretto. È come dire che Wells Fargo può impersonare la Bank of America se ha la stessa CA. Un certificato X509 ha un DN oggetto che può essere convalidato per l'identità corretta.
Paul Draper,

+1 soprattutto per identificare che questo fa parte della specifica della firma digitale XML, qualcosa che è meno che ovvio per un principiante e cruciale per capire come i messaggi vengono effettivamente elaborati, poiché praticamente ogni implementazione SAML si basa su una libreria XML per fare il sollevamento pesante.
BryKKan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.