SAML: Mengapa sertifikat dalam Tanda Tangan?

103

Saya harus menerapkan SSO dengan SAML untuk situs web perusahaan saya (sebagai pihak yang mengandalkan). Bagian penting dari kursus adalah verifikasi tanda tangan. Berikut adalah bagian tanda tangan dari sampel SAML dari perusahaan mitra kami (pihak yang menegaskan):

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

Yang tidak saya mengerti adalah, mengapa sertifikat di dalam tanda tangan?

Maksud saya, biasanya saya mendapatkan sertifikat dari perusahaan dengan cara yang aman, jadi saya tahu sertifikat itu dari mereka. Dan ketika verifikasi tanda tangan berhasil, saya tahu perusahaan mitra kami telah menandatanganinya.

Tetapi jika sertifikat tersebut berada dalam tanda tangan SAML-Response, siapa pun dapat mengirimkannya! Satu-satunya hal yang saya tahu adalah bahwa tanggapan tersebut belum dipalsukan. Tapi intinya, saya tidak tahu siapa yang mengirim SAML.

Adakah yang bisa menjelaskan kepada saya, bagaimana cara kerjanya?

Dante
sumber

Jawaban:

66

Tanggapan SAML datang dengan tanda tangan dan kunci publik untuk tanda tangan itu.

Anda dapat menggunakan kunci publik untuk memverifikasi bahwa konten respons SAML cocok dengan kunci - dengan kata lain - respons tersebut pasti datang dari seseorang yang memiliki kunci privat yang cocok dengan kunci publik dalam pesan, dan responsnya belum. dirusak.

Saya tidak tahu teknologi apa yang Anda kerjakan, tetapi di .Net Anda dapat memeriksanya seperti ini:

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

Itu hanya memeriksa bahwa pesan itu dari siapa yang dikatakannya. Anda memerlukan pemeriksaan tambahan bahwa pesan tersebut berasal dari seseorang yang Anda percaya, dan pemeriksaan ini lebih lambat - perlu menyertakan pencabutan dan mungkin perlu memverifikasi seluruh rantai sertifikat.

Biasanya ini akan menjadi daftar kunci publik tempat Anda akan menerima tanggapan SAML.

Kemudian Anda dapat memeriksa bahwa pesan ini belum diubah, dan berasal dari seseorang yang Anda percayai, sehingga Anda dapat memberi otorisasi detail pengguna yang diberikan dalam atribut SAML yang disediakan.

Anda bisa saja sudah memiliki kunci publik, yang berarti bahwa tanda tangan tidak perlu menyertakan kunci publik lagi, tetapi Anda juga bisa memiliki beberapa kemungkinan pengirim yang dikenal, atau bahkan rantai pengirim yang dikenal.

Misalnya, Anda mungkin memiliki dua penyedia tepercaya - dalam kedua kasus Anda memeriksa bahwa pesan belum diubah sebelum memeriksa apakah Anda mempercayai salah satu penyedia. Jika kunci tidak ada dalam tanda tangan, pernyataannya bisa sedikit lebih kecil, tetapi sekarang Anda harus tahu sebelumnya dari penyedia identitas mana asersi tersebut berasal.

Jadi, sebenarnya, ada dua alasan utama mengapa kunci publik ada di dalam tanda tangan:

  1. Pemeriksaan gangguan lebih cepat daripada pemeriksaan identitas, dan dapat diisolasi jika kunci publik diketahui.
  2. Banyak identitas jauh lebih mudah untuk didukung jika kuncinya ada dalam pernyataan.
Keith
sumber
2
@svlada pernyataan SAML tidak memerlukan enkripsi sendiri, karena teks itu sendiri dapat dikirim melalui SSL - seluruh sesi pengguna harus HTTPS. Mengingat bahwa verifikasi bahwa pengirim yang dikenal dan tepercaya menandatangani pernyataan tersebut dan belum dirusak sudah cukup.
Keith
5
@svlada tidak boleh ada otentikasi berbasis HTTP (dalam bentuk apa pun) tanpa SSL. Mengenkripsi sertifikat akan menghentikan orang di tengah (MitM) untuk membacanya, tetapi tidak akan menghentikan mereka untuk menggunakannya kembali dengan cara yang mirip dengan serangan MitM berbasis cookie.
Keith
8
Respons SAML tidak memerlukan kunci publik untuk tanda tangan itu. Bagian 5.4.5 dari spesifikasi SAML2 menyatakan "Tanda Tangan XML mendefinisikan penggunaan elemen <ds: KeyInfo>. SAML tidak memerlukan penggunaan <ds: KeyInfo>, juga tidak memberlakukan pembatasan apa pun pada penggunaannya. Oleh karena itu, <ds : KeyInfo> MUNGKIN tidak ada. " Anda dapat memverifikasi tanda tangan jika kunci publik telah diberikan kepada Anda melalui cara lain, misalnya disimpan di penyimpanan sertifikat lokal Anda sebelum menerapkan konsumen SAML.
Sam Rueby
2
@ Sam.Rueby ah, saya akan memperbaikinya. Setiap implementasi yang saya lihat telah menyertakan kuncinya.
Keith
5
@Jez seluruh protokol ini sangat membingungkan. Pada dasarnya pernyataan itu berdiri sendiri - Anda dapat memeriksa bahwa itu belum dirusak sejak kunci pribadi menandatanganinya. Anda dapat melakukan ini tanpa memiliki kunci publik itu sendiri (jadi saya tahu pernyataan ini datang dari Dave, dan bahwa tidak ada yang mengubahnya sejak Dave menandatanganinya, tetapi saya mungkin tidak tahu siapa Dave atau apakah saya dapat mempercayainya). Kemudian, setelah memverifikasi itu, saya dapat memeriksa kunci publik yang saya percayai. Saya pikir ini karena mungkin ada penundaan pada pemeriksaan terakhir itu (sementara saya bertanya tentang kantor apakah ada yang tahu Dave)
Keith
41

Alasan kunci ditentukan adalah karena Metadata untuk Penyedia Identitas dapat menentukan beberapa kunci penandatanganan, dan Anda dapat menentukan kunci yang akan digunakan dengan menyertakannya dengan tanda tangan. SAML 2.0 mensyaratkan bahwa jika kunci tidak ditentukan dengan Assertion, maka dapat disimpulkan berdasarkan konteks (dari Metadata untuk pihak yang menegaskan).

Misalnya, Anda mungkin memiliki ini di Metadata Anda untuk pihak yang menegaskan:

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

Setiap elemen XML yang ditandatangani dapat menentukan kunci mana yang digunakan untuk tanda tangan. Namun, dengan kasus SAML 2.0, kunci penandatanganan tersebut harus (misalnya) cocok dengan salah satu yang ditentukan di Metadata untuk pihak yang membuat tanda tangan. Jika kunci yang diberikan dengan tanda tangan tidak tepercaya (tidak ditentukan dalam Metadata dalam kasus ini), maka sistem SAML harus menghasilkan kesalahan saat memvalidasi tanda tangan.

jbindel.dll
sumber
9
Saya pikir ini adalah poin penting, bahwa sertifikat dalam tanggapan harus cocok dengan sertifikat di metadata. Jika tidak, saya dapat menandatangani tanggapan dengan sertifikat apa pun yang saya inginkan dan mengirim kunci publiknya untuk verifikasi.
dana
5
Saya pikir ini adalah jawaban terbaik, menurut saya yang lain kehilangan poin bahwa memeriksa pesan terhadap kunci yang dinyatakan dalam pesan itu sendiri tidak memberi Anda keamanan apa pun ... Anda tetap harus memeriksa kunci dalam pesan benar! (dalam hal ini, Anda harus memastikannya dalam metadata tepercaya).
rchampourlier
3
Setuju sepenuhnya dengan komentar di atas - sertifikat yang diteruskan dalam pesan tidak berharga dengan sendirinya karena inti penandatanganan adalah untuk memverifikasi bahwa pesan tersebut dapat dipercaya. Jika pesan tidak dapat dipercaya, begitu pula sertifikat yang dibundel.
Jez
@jbindel - terima kasih! Saya punya pertanyaan newby jika memungkinkan: Apakah sertifikat SAML ini harus cocok dengan sertifikat fisik saat ini, atau hanya digunakan untuk mencapai kecocokan metadata? Saya menanyakan hal ini karena saya prihatin tentang dampak operasional IdP yang menyimpan kembali sertifikat mereka - pada titik mana mungkin itu tidak sinkron dengan kunci metadata. Jika 2 seri, maka saya khawatir lagi. dampak operasional yaitu. bahwa hingga SP dan IdP memperbarui kunci SAML2 secara manual, semua SSO akan gagal, dan akibatnya berdampak pada pengguna SSO jika komunikasi teknis tidak sempurna. (maaf jika pertanyaan bodoh)
Pancho
Metadata SP harus menyertakan sertifikat, tetapi metadata SP dapat menentukan sertifikat IdP lama dan baru. Jika IdP memperbarui sertifikatnya, maka itu dapat ditambahkan ke metadata SP. Setelah IdP seharusnya dilakukan menggunakan sertifikat lama, Anda dapat menghapusnya dari metadata SP. Apakah itu menjawab pertanyaan Anda? Saya tahu ini bekerja dengan baik di Shibboleth SP. File metadata SP hanya perlu memiliki <KeyDescriptor use="signing">elemen untuk sertifikat IdP yang akan diterima oleh SP.
jbindel
8

Bagian publik dari sertifikat penandatanganan ada dalam pesan SAML. Ini digunakan untuk memeriksa tanda tangan untuk token itu sendiri, dan tentu saja untuk memungkinkan penerima mengetahui siapa yang menerbitkan token dan memperlakukannya dengan semestinya.

Fakta bahwa itu ada di sana adalah bagian dari spesifikasi tanda tangan digital XML, itu sebenarnya bukan sesuatu yang spesifik untuk SAML. Tanpa sertifikat, bagaimana Anda bisa tahu dari mana token itu berasal, dan bagaimana Anda bisa memvalidasinya?

XmlDSig menentukan metode lain, Anda dapat mengidentifikasi kunci penandatanganan berdasarkan subjek, nomor seri, hash, dll., Tetapi ini mengasumsikan bahwa pihak penerima memiliki sertifikat publik. Untuk SAML ini mungkin tidak terjadi, karenanya penyematan bagian publik dari sertifikat X509.

blowdart
sumber
1
"Tanpa sertifikat, bagaimana Anda bisa tahu dari mana token itu berasal, dan bagaimana Anda bisa memvalidasinya?" - apa yang kamu bicarakan? Untuk mempercayai tanda tangan dalam pesan SAML, Anda harus sudah memiliki daftar sertifikat publik tepercaya. Anda dapat menggunakan Issuerelemen dan menyimpan sertifikat penerbit itu, dan memilih sertifikat yang akan digunakan untuk memeriksa tanda tangan untuk pesan ini.
Jez
2
Tidak benar sama sekali, Jez. Anda dapat mempercayai penerbit sertifikat, seperti CA, tanpa harus mempercayai setiap sertifikat yang dikeluarkannya dan tanpa harus menyimpan salinan lokal setiap sertifikat.
blowdart
3
blowdart yang berarti Anda mempercayai token saml yang ditandatangani oleh sertifikat valid lainnya yang dikeluarkan oleh CA. Bukan tidak mungkin untuk membelinya! Untuk memastikan token Anda berasal dari sumber yang benar seperti yang disebutkan @Jez, Anda harus sudah memiliki daftar sertifikat publik tepercaya.
Minggu
2
@Sun, salah. Itu seperti mengatakan Wells Fargo dapat menyamar sebagai Bank of America jika mereka memiliki CA yang sama. Sertifikat X509 memiliki DN Subjek yang dapat divalidasi untuk identitas yang benar.
Paul Draper
+1 terutama untuk mengidentifikasi bahwa ini adalah bagian dari spesifikasi tanda tangan digital XML, sesuatu yang kurang jelas bagi pemula dan penting untuk memahami bagaimana pesan sebenarnya diproses, karena hampir setiap implementasi SAML bergantung pada pustaka XML untuk melakukan angkat berat.
BryKKan