SAML: dlaczego certyfikat znajduje się w podpisie?

103

Muszę wdrożyć logowanie jednokrotne przy użyciu SAML w witrynie mojej firmy (jako strona ufająca). Istotną częścią kursu jest weryfikacja podpisu. Oto część podpisu przykładowego SAML od naszej firmy partnerskiej (strona potwierdzająca):

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

Nie rozumiem tylko, dlaczego certyfikat znajduje się w podpisie?

Mam na myśli to, że zwykle otrzymuję certyfikat od firmy w bezpieczny sposób, więc wiem, że certyfikat pochodzi od niej. A kiedy weryfikacja podpisu się powiedzie, wiem, że podpisała go nasza firma partnerska.

Ale jeśli certyfikat znajduje się w podpisie odpowiedzi SAML, każdy mógł go wysłać! Wiem tylko, że odpowiedź nie została sfałszowana. Ale chodzi o to, że nie mam pojęcia, kto wysłał SAML.

Czy ktoś może mi wyjaśnić, jak to działa?

Dante
źródło

Odpowiedzi:

66

Odpowiedzi SAML są dostarczane z podpisem i kluczem publicznym dla tego podpisu.

Możesz użyć klucza publicznego, aby sprawdzić, czy treść odpowiedzi SAML jest zgodna z kluczem - innymi słowy - ta odpowiedź na pewno pochodzi od kogoś, kto ma pasujący klucz prywatny do klucza publicznego w wiadomości, a odpowiedź nie została naruszone.

Nie wiem, z jaką technologią pracujesz, ale w .Net możesz to sprawdzić w ten sposób:

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

To tylko sprawdza, czy wiadomość pochodzi od tego, kogo podaje. Potrzebujesz dodatkowego sprawdzenia, czy wiadomość pochodzi od kogoś, komu ufasz, a to sprawdzenie jest wolniejsze - musi obejmować unieważnienie i może wymagać zweryfikowania całego łańcucha certyfikatów.

Zwykle będzie to lista kluczy publicznych, z których można akceptować odpowiedzi SAML.

Następnie możesz sprawdzić, czy ta wiadomość nie została zmieniona i czy pochodzi od zaufanej osoby, dzięki czemu możesz autoryzować dane użytkownika podane w dostarczonych atrybutach SAML.

Państwo mogło już mieć klucz publiczny, co oznacza, że podpis nie ma potrzeby ponownie zawierać klucz publiczny, ale można też mieć wiele możliwych znanych nadawców, a nawet łańcuch znanych nadawców.

Na przykład możesz mieć dwóch zaufanych dostawców - w każdym przypadku sprawdzasz, czy wiadomość nie została zmodyfikowana, zanim sprawdzisz, czy ufasz jednemu dostawcy. Jeśli klucza nie ma w podpisie, potwierdzenia mogą być nieco mniejsze, ale teraz musisz wcześniej wiedzieć, od którego dostawcy tożsamości pochodzi potwierdzenie.

Tak naprawdę istnieją dwa główne powody, dla których klucz publiczny znajduje się w podpisie:

  1. Kontrola manipulacji jest szybsza niż kontrola tożsamości i może zostać odizolowana, jeśli znany jest klucz publiczny.
  2. Obsługa wielu tożsamości jest znacznie łatwiejsza, jeśli klucz znajduje się w asercji.
Keith
źródło
2
@svlada asercja SAML nie wymaga własnego szyfrowania, ponieważ sam tekst może być przesyłany przez SSL - cała sesja użytkownika powinna być HTTPS. Biorąc pod uwagę, że wystarczy zweryfikowanie, że znany, zaufany nadawca podpisał potwierdzenie i nie został on zmodyfikowany.
Keith
5
@svlada Żadne uwierzytelnianie oparte na protokole HTTP (jakiegokolwiek rodzaju) nie powinno być nigdy wykonywane bez SSL. Zaszyfrowanie certyfikatu powstrzyma człowieka pośrodku (MitM) przed jego odczytaniem, ale nie powstrzyma go przed ponownym użyciem go w podobny sposób, jak w przypadku ataku MitM opartego na plikach cookie.
Keith
8
Odpowiedzi SAML nie wymagają dołączania klucza publicznego dla tego podpisu. Sekcja 5.4.5 specyfikacji SAML2 stwierdza, że ​​„Podpis XML definiuje użycie elementu <ds: KeyInfo>. SAML nie wymaga użycia elementu <ds: KeyInfo> ani nie nakłada żadnych ograniczeń na jego użycie. Dlatego <ds : KeyInfo> MOŻE być nieobecne. " Możesz zweryfikować podpis, jeśli klucz publiczny został dostarczony w inny sposób, np. Przechowywany w lokalnym magazynie certyfikatów przed wdrożeniem konsumenta SAML.
Sam Rueby,
2
@ Sam.Rueby ah, poprawię to. Każda implementacja, którą widziałem, zawierała klucz.
Keith
5
@Jez, cały ten protokół jest tak zagmatwany jak diabli. Zasadniczo potwierdzenie jest niezależne - możesz sprawdzić, czy nie zostało zmienione od czasu podpisania klucza prywatnego. Możesz to zrobić bez posiadania tego klucza publicznego samodzielnie (więc wiem, że to stwierdzenie pochodzi od Dave'a i że nikt nie majstrował przy nim od czasu podpisania go przez Dave'a, ale mogę nie mieć pojęcia, kim jest Dave i czy mogę mu zaufać). Następnie, po zweryfikowaniu tego, mogę sprawdzić, czy klucz publiczny jest tym, któremu ufam. Myślę, że dzieje się tak dlatego, że może wystąpić opóźnienie w ostatecznym sprawdzeniu (kiedy pytam o biuro, czy ktoś zna Dave'a)
Keith
41

Powodem, dla którego klucz został określony, jest to, że metadane dla dostawcy tożsamości mogą określać wiele kluczy podpisywania, a klucz do użycia można określić, dołączając go do podpisu. SAML 2.0 wymaga, aby jeśli klucz nie został określony za pomocą parametru Assertion, można go wywnioskować na podstawie kontekstu (z metadanych strony potwierdzającej).

Na przykład możesz mieć to w swoich metadanych dla strony zgłaszającej:

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

Każdy podpisywany element XML może określać, który klucz jest używany do podpisu. Jednak w przypadku SAML 2.0 ten klucz podpisu musi (na przykład) odpowiadać kluczowi zdefiniowanemu w Metadanych dla strony generującej podpis. Jeśli klucz dostarczony z podpisem nie jest zaufany (w tym przypadku nie jest określony w Metadanych), system SAML musi wygenerować błąd podczas weryfikacji podpisu.

jbindel
źródło
9
Myślę, że jest to ważny punkt, aby certyfikat w odpowiedzi był zgodny z certyfikatem w metadanych. W przeciwnym razie mógłbym podpisać odpowiedź dowolnym certyfikatem i wysłać jego klucz publiczny do weryfikacji.
dana
5
Myślę, że to najlepsza odpowiedź, wydaje mi się, że innym mi nie chodzi o to, że sprawdzenie wiadomości z kluczem zadeklarowanym w samej wiadomości nie daje żadnych zabezpieczeń ... Nadal musisz sprawdzić klucz w wiadomości jest w porządku! (w tym przypadku musisz upewnić się, że znajduje się w zaufanych metadanych).
rchampourlier
3
Całkowicie zgadzam się z powyższymi uwagami - certyfikat przekazany w wiadomości jest sam w sobie bezwartościowy , ponieważ celem podpisu jest sprawdzenie, czy wiadomość jest godna zaufania. Jeśli wiadomość nie jest godna zaufania, nie są też dołączone do niej certyfikaty.
Jez
@jbindel - dziękujemy! Jeśli to możliwe, mam nowe pytanie: czy ten certyfikat SAML musi być zgodny z bieżącym certyfikatem fizycznym, czy jest używany tylko do uzyskania zgodności metadanych? Pytam o to, ponieważ jestem zaniepokojony operacyjnymi skutkami ponownego wprowadzenia klucza przez dostawcę tożsamości - w którym to momencie prawdopodobnie traci synchronizację z kluczem metadanych. Jeśli 2 są remisowe, martwię się ponownie. wpływ operacyjny tj. że dopóki dostawcy usług i dostawcy tożsamości nie zaktualizują ręcznie klucza SAML2, wszystkie logowanie jednokrotne nie powiedzie się, a niedoskonała komunikacja techniczna będzie miała wpływ na użytkowników SSO. (przepraszam za głupie pytanie)
Pancho
Metadane SP muszą zawierać certyfikat, ale metadane SP mogą określać zarówno stary, jak i nowy certyfikat dostawcy tożsamości. Jeśli dostawca tożsamości aktualizuje swój certyfikat, można go dodać do metadanych SP. Gdy IdP ma zostać wykonane przy użyciu starego certyfikatu, możesz usunąć go z metadanych SP. Czy to odnosi się do tego, o co pytasz? Wiem, że działa to doskonale na Shibboleth SP. Plik metadanych SP musi tylko zawierać <KeyDescriptor use="signing">elementy certyfikatów IdP, które zostaną zaakceptowane przez SP.
jbindel,
8

Publiczna część certyfikatu podpisywania znajduje się w komunikacie SAML. Służy to do sprawdzania podpisu samego tokena i oczywiście umożliwia odbiorcom określenie, kto wydał token, i odpowiednie traktowanie go.

Fakt, że jest tam, jest częścią specyfikacji podpisu cyfrowego XML, nie jest to tak naprawdę nic specyficznego dla SAML. Jak bez certyfikatu można było stwierdzić, skąd pochodzi token i jak można go zweryfikować?

XmlDSig określa inne metody, możesz zidentyfikować klucz podpisywania według tematu, numeru seryjnego, skrótu itp., Ale zakłada się, że strona odbierająca ma certyfikat publiczny. W przypadku SAML może tak nie być, stąd osadzenie publicznej części certyfikatu X509.

strzałka do dmuchawki
źródło
1
„Bez certyfikatu jak można było stwierdzić, skąd pochodzi token i jak można go zweryfikować?” - o czym mówisz? Aby zaufać podpisowi w wiadomości SAML, musisz mieć już listę zaufanych certyfikatów publicznych. Możesz użyć Issuerelementu i zapisać na nim certyfikat tego wystawcy, a następnie wybrać ten certyfikat, na podstawie którego sprawdzisz podpis tej wiadomości.
Jez,
2
Wcale nieprawda Jez. Możesz zaufać wystawcy certyfikatu, takiemu jak CA, bez konieczności ufania poszczególnym wystawionym przez siebie certyfikatom i bez konieczności przechowywania lokalnych kopii każdego certyfikatu.
blowdart
3
blowdart, co oznacza, że ​​ufasz tokenowi SAML podpisanemu przez inny ważny certyfikat wydany przez CA. Nie można go kupić! Aby upewnić się, że token pochodzi z właściwego źródła, o czym wspomniał @Jez, powinieneś mieć już listę zaufanych certyfikatów publicznych.
Niedziela,
2
@ Słońce, niepoprawne. To tak, jakby powiedzieć, że Wells Fargo może podszywać się pod Bank of America, jeśli ma ten sam CA. Certyfikat X509 ma nazwę wyróżniającą podmiotu, którą można zweryfikować pod kątem prawidłowej tożsamości.
Paul Draper
+1 zwłaszcza w celu zidentyfikowania, że ​​jest to część specyfikacji podpisu cyfrowego XML, co jest mniej niż oczywiste dla nowicjusza i ma kluczowe znaczenie dla zrozumienia, jak wiadomości są faktycznie przetwarzane, ponieważ prawie każda implementacja SAML opiera się na bibliotece XML do podnoszenie ciężarów.
BryKKan