SAML: Почему сертификат находится в подписи?

104

Мне нужно внедрить систему единого входа с 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-ответа, его мог отправить любой! Единственное, что я знаю, это то, что ответ не был сфальсифицирован. Но дело в том, что я понятия не имею, кто отправил SAML.

Может ли кто-нибудь объяснить мне, как это работает?

Данте
источник

Ответы:

66

Ответы SAML содержат подпись и открытый ключ для этой подписи.

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

Я не знаю, с какой технологией вы работаете, но в .Net вы можете проверить это так:

// 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. Поддерживать множественные идентификаторы намного проще, если ключ находится в утверждении.
Кит
источник
3
@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, весь этот протокол чертовски запутан. По сути, утверждение является самодостаточным - вы можете убедиться, что оно не было изменено с момента его подписания закрытым ключом. Вы можете сделать это сами, не имея этого открытого ключа (так что я знаю, что это утверждение исходило от Дэйва, и что никто не вмешивался в него с тех пор, как Дэйв подписал его, но я, возможно, понятия не имею, кто такой Дэйв и могу ли я ему доверять). Затем, убедившись в этом, я могу проверить, является ли открытый ключ тем, которому я доверяю. Я думаю, это потому, что может быть задержка с последней проверкой (пока я иду спрашивать в офисе, знает ли кто-нибудь Дэйва)
Кит
42

Причина, по которой в ответе SAML указывается открытый ключ, заключается в том, что метаданные для поставщика удостоверений могут указывать несколько открытых ключей. Это позволяет провайдеру идентификации (подтверждающей стороне) указать провайдеру услуг (проверяющей стороне) правильный открытый ключ, который будет использоваться для проверки подписи в ответе SAML.

Например, метаданные утверждающей стороны могут выглядеть следующим образом:

<KeyDescriptor>
    <ds:KeyInfo>
        <ds:X509Data>
            <ds:X509Certificate>BQUAMCMBgN...XerfXHHEZYZs=</ds:X509Certificate>
        </ds:X509Data>
        <ds:X509Data>
            <ds:X509Certificate>H24a88h7zl...2zo28hH5DK78=</ds:X509Certificate>
        </ds:X509Data>
    </ds:KeyInfo>
</KeyDescriptor>

Хотя SAML 2.0 не требует включения открытого ключа, я не встречал поставщиков удостоверений, которые не включают открытый ключ в свой ответ SAML. Если открытый ключ не указан в утверждении, он должен быть выведен через метаданные поставщика удостоверений.

С точки зрения доверия к открытому ключу, отправляемому в ответе, открытый ключ должен соответствовать тому, который определен в метаданных поставщика удостоверений. Эти данные метаданных обычно предоставляются вашими клиентами, которые хотят использовать SSO для доступа к вашему приложению - вы будете точно знать, какой открытый ключ (и) нужно искать (т.е. вы, вероятно, попросите их предоставить вам URL-адрес метаданных своего поставщика удостоверений, чтобы вы можете получить их метаданные и получить соответствующую информацию, такую ​​как открытые ключи, конечная точка эмитента и т. д.).

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

jbindel
источник
10
Я думаю, что это важный момент, что сертификат в ответе должен соответствовать сертификату в метаданных. В противном случае я мог бы подписать ответ любым желаемым сертификатом и отправить его открытый ключ на проверку.
dana
6
Я думаю, что это лучший ответ, мне кажется, что в других не хватает того момента, что проверка сообщения по ключу, объявленному в самом сообщении, не дает вам никакой безопасности ... Вы все равно должны проверить ключ в сообщении верно! (в этом случае вы должны убедиться, что это надежные метаданные).
rchampourlier
4
Полностью согласен с приведенными выше комментариями - сертификат, переданный в сообщении, бесполезен сам по себе, потому что весь смысл подписи заключается в том, чтобы убедиться, что сообщение заслуживает доверия. Если сообщение не заслуживает доверия, то и связанные сертификаты тоже.
Jez
@jbindel - спасибо! У меня есть новый вопрос, если это возможно: должен ли этот сертификат SAML соответствовать текущему физическому сертификату или он используется только для достижения соответствия метаданных? Я спрашиваю об этом, так как меня беспокоит влияние на работу IdP, изменяющего ключи своего сертификата - в этот момент предположительно он теряет синхронизацию с ключом метаданных. Если 2 равны, то меня беспокоит. эксплуатационное воздействие, т.е. что до тех пор, пока SP и IdP не обновят ключ SAML2 вручную, все системы единого входа не будут работать, что, в свою очередь, повлияет на пользователей системы единого входа в случае несовершенной технической связи. (извиняюсь за глупый вопрос)
Панчо
Метаданные 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
Совсем неправда, Джез. Вы можете доверять издателю сертификата, например центру сертификации, без необходимости доверять отдельным сертификатам, которые он выдает, и без необходимости хранить локальные копии каждого сертификата.
blowdart
4
blowdart, что означает, что вы доверяете токену saml, подписанному любым другим действительным сертификатом, выданным CA. Купить его невозможно! Чтобы убедиться, что ваш токен поступает из правильного источника, как упоминал @Jez, у вас уже должен быть список доверенных общедоступных сертификатов.
Вс,
2
@ Sun, неверно. Это все равно, что сказать, что Wells Fargo может выдавать себя за Bank of America, если у них один и тот же CA. Сертификат X509 имеет DN субъекта, подлинность которого может быть подтверждена.
Пол Дрейпер
+1 особенно для определения того, что это часть спецификации цифровой подписи XML, что не так очевидно для новичка и имеет решающее значение для понимания того, как на самом деле обрабатываются сообщения, поскольку почти каждая реализация SAML полагается на библиотеку XML для выполнения тяжелая атлетика.
BryKKan