SAML: Чому сертифікат є підписом?


103

Мені належить впровадити SSO з SAML для веб-сайту своєї компанії (як покладається сторона). Важливою частиною поза курсом є перевірка підпису. Ось частина підпису зразка SAML від нашої компанії-партнера (стверджуючої сторони):

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

Я просто не розумію, чому сертифікат є підписом?

Я маю на увазі, як правило, я отримую сертифікат від компанії в безпечному вигляді, тому я знаю, що сертифікат від них. І коли перевірка підпису проходить успішно, я знаю, що наша компанія-партнер підписала його.

Але коли сертифікат знаходиться в підписі SAML-Response, кожен міг би його надіслати! Я знаю єдине, що відповідь не була фальсифікована. Але справа в тому, що я не маю уявлення, хто надіслав SAML.

Хтось може мені пояснити, як це працює?

Відповіді:


66

Відповіді SAML мають підпис та відкритий ключ для цього підпису.

Ви можете скористатися відкритим ключем, щоб переконатися, що вміст відповіді SAML відповідає ключовому - іншими словами, що відповідь, безумовно, надійшла від того, хто має відповідне приватний ключ до відкритого ключа в повідомленні, і відповідь не була підроблений.

Я не знаю, з якими технологіями ви працюєте, але в. Ні. Ви можете перевірити це так:

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

Це просто перевіряє, що повідомлення є від того, хто це каже. Вам потрібна додаткова перевірка того, що повідомлення надійшло від того, кому ви довіряєте, і ця перевірка повільніша - вона повинна включати анулювання та може знадобитися перевірити цілий ланцюжок сертифікатів.

Зазвичай це список відкритих ключів, від яких ви приймаєте відповіді SAML.

Тоді ви можете перевірити, чи це повідомлення не було підроблено, і чи є воно від того, кому ви довіряєте, тож ви можете авторизувати дані користувача, надані в наданих атрибутах SAML.

Ви могли б вже мати відкритий ключ, а це означає , що підпис не повинна включати відкритий ключ знову, але ви також можете мати кілька можливих відомі відправник, або навіть ланцюг відомих відправників.

Наприклад, у вас можуть бути два надійних постачальника - в будь-якому випадку ви перевіряєте, чи це повідомлення не було підроблене, перш ніж перевірити, чи довіряєте ви будь-якому постачальнику. Якщо ключ відсутній у підписі, твердження можуть бути трохи меншими, але тепер ви повинні заздалегідь знати, від якого постачальника ідентифікаторів отримано твердження.

Тож справді є дві основні причини того, що відкритий ключ є в підписі:

  1. Перевірка підробок швидша, ніж перевірка особи, і може бути ізольована, якщо відкритий ключ відомий.
  2. Кілька ідентичностей набагато простіше підтримувати, якщо ключ у твердженні.

2
@svlada твердження SAML не потребує власного шифрування, оскільки сам текст може надсилатися через SSL - весь сеанс користувача повинен бути HTTPS. Враховуючи те, що перевірка того, що відомий надійний відправник підписала це твердження і що його не було підроблено, достатньо.
Кіт

5
@svlada жодна аутентифікація на основі HTTP (будь-якого типу) ніколи не повинна здійснюватися без SSL. Шифрування сертифіката зупинить людину в середині (MitM) від його читання, але це не зупинить їх повторного використання аналогічним чином як на атаку MitM на основі cookie.
Кіт

8
Відповіді SAML не вимагають включення відкритого ключа для цього підпису. Розділ 5.4.5 специфікації SAML2 зазначає, що "XML-підпис визначає використання елемента <ds: KeyInfo>. SAML не вимагає використання <ds: KeyInfo>, а також не встановлює жодних обмежень на його використання. Тому <ds : KeyInfo> МОЖЕ бути відсутнім. " Ви можете перевірити підпис, якщо відкритий ключ був наданий вам іншими способами, наприклад, зберігається у вашому локальному магазині сертифікатів до впровадження споживача SAML.
Сем Рюбі

2
@ Sam.Rueby ах, я виправлю це. Кожна реалізація, яку я бачив, містила ключ.
Кіт

5
@Jez весь цей протокол настільки ж заплутаний, як і пекло. В основному твердження є автономним - ви можете перевірити, що воно не було підроблене з моменту підписання приватного ключа. Ви можете це зробити, не маючи цього відкритого ключа самостійно (тому я знаю, що це твердження надійшло від Дейва, і що ніхто не підробляв це, з тих пір, як Дейв його підписав, але я, мабуть, не маю уявлення, хто такий Дейв, чи я можу йому довіряти). Потім, перевіривши це, я можу перевірити відкритий ключ - це той, кому я довіряю. Я думаю, це тому, що може бути затримка з цією остаточною перевіркою (поки я йду запитати про офіс, чи хтось знає Дейва)
Кіт,

41

Причина, за якою вказано ключ, полягає в тому, що метадані провайдера ідентичності можуть задавати кілька ключів підпису, а ви можете вказати ключ для використання, включивши його в підпис. SAML 2.0 вимагає, що якщо ключ не вказаний разом із Assertionсимволом, то він може бути виведений за контекстом (з метаданих для сторони, що стверджує).

Наприклад, це може бути у ваших метаданих для учасника, який стверджує:

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

Кожен підписаний XML-елемент може вказати, який ключ використовується для підпису. Однак у випадку SAML 2.0 цей ключ підпису повинен (наприклад) відповідати тому, який визначений у метаданих для сторони, яка генерує підпис. Якщо ключ, наданий підписом, не довіряється (не вказаний у метаданих у цьому випадку), то система SAML повинна генерувати помилку під час перевірки підпису.


9
Я думаю, що це важливий момент, що сертифікат у відповіді повинен відповідати сертифікату в метаданих. В іншому випадку я можу підписати відповідь будь-яким сертифікатом, який я хотів, і надіслати його відкритий ключ для перевірки.
дата

5
Я думаю, що це найкраща відповідь, мені здається, інші не вистачають того, що перевірка повідомлення проти ключа, заявленого в повідомленні, не дає вам ніякої безпеки ... Ви все одно повинні перевірити ключ у повідомленні правильно! (у цьому випадку ви повинні переконатися, що вони містять надійні метадані).
rchampourlier

3
Цілком погоджуйтеся з вищезазначеними коментарями - сертифікат, переданий у повідомленні , сам по собі не вартий , оскільки вся суть підписання полягає у тому, щоб перевірити, чи є повідомлення надійним. Якщо повідомлення не заслуговує на довіру, не застосовуються також пакетні сертифікати.
Jez

@jbindel - дякую! У мене виникає нове запитання, якщо можливо: чи повинен цей сертифікат SAML відповідати поточному фізичному сертифікату чи він використовується лише для досягнення відповідності метаданих? Я запитую це, оскільки мене турбує операційний вплив IdP, який переробляє їх сертифікат - імовірно, він виходить із синхронізації з ключем метаданих. Якщо два зв'язані, то мене турбує повторне. оперативний вплив, тобто. що доки SP і IdP не оновлюють вручну ключ SAML2, всі SSO вийдуть з ладу і, як наслідок, вплив на користувачів SSO, якщо недосконалі технічні зручності. (вибачення, якщо дурне запитання)
Панчо

Метадані SP повинні включати сертифікат, але метадані SP можуть визначати як старі, так і нові сертифікати IdP. Якщо IdP оновлює свій сертифікат, то його можна додати до метаданих SP. Після того, як IdP повинен бути виконаний за допомогою старого сертифіката, його можна видалити з метаданих SP. Чи відповідає це те, що ви запитуєте? Я знаю, що це чудово працює на Shibboleth SP. Файл метаданих SP просто повинен мати <KeyDescriptor use="signing">елементи для сертифікатів IdP, які будуть прийняті SP.
jbindel

8

Публічна частина сертифіката для підписання знаходиться у повідомленні SAML. Це використовується для перевірки підпису для самого маркера, і, звичайно, для того, щоб одержувачі могли сказати, хто видав маркер, і обробити його відповідно.

Той факт, що він знаходиться там, є частиною специфікацій цифрового підпису XML, це насправді не є щось специфічне SAML. Без сертифіката ви могли б сказати, звідки взявся маркер, і як ви могли його перевірити?

XmlDSig вказує інші методи, ви можете ідентифікувати ключ підпису за темою, серійним номером, хешем тощо, але це передбачає, що приймаюча сторона має публічний сертифікат. Для SAML це може бути не так, отже, вбудовування загальнодоступної частини керта X509.


1
"Без сертифіката ви могли сказати, звідки походить маркер, і як ви могли його перевірити?" - про що ти говориш? Щоб довіряти підпису в повідомленні SAML, ви вже повинні мати список довірених публічних сертифікатів. Ви можете використовувати Issuerелемент і зберігати сертифікат цього емітента проти цього, а також вибрати той сертифікат, на якому перевіряти підпис цього повідомлення.
Jez

2
Не зовсім правда Jez. Ви можете довіряти видавцю сертифікатів, як ЦА, без довіри окремих сертифікатів, які він видає, і без необхідності зберігати локальні копії кожного сертифіката.
blowdart

3
blowdart, що означає, що ви довіряєте маркер saml, підписаний будь-яким іншим дійсним сертифікатом, виданим CA. Придбати його не неможливо! Щоб переконатися, що ваш маркер надходить з правильного джерела, як згадував @Jez, у вас уже повинен бути список надійних публічних сертифікатів.
Нд

2
@ Не, неправильно. Це як би сказати, що Уеллс Фарго може представити себе Банком Америки, якщо вони мають ту саму Ц.А. Сертифікат X509 має суб'єктний DN, який може бути підтверджений для правильної ідентичності.
Пол Дрейпер

+1, особливо для визначення того, що це частина специфікації цифрового підпису XML, що є менш очевидним для новачків і вирішальним для розуміння того, як фактично обробляються повідомлення, оскільки майже кожна реалізація SAML покладається на бібліотеку XML, щоб зробити важкий підйом.
BryKKan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.