SAML : 인증서가 서명 내에있는 이유는 무엇입니까?


103

회사 웹 사이트 (신뢰 당사자)에 대해 SAML을 사용하여 SSO를 구현해야합니다. 과정에서 필수적인 부분은 서명 확인입니다. 다음은 파트너 회사 (어설 션 당사자)의 샘플 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 응답의 내용이 키와 일치하는지 확인할 수 있습니다. 변조.

어떤 기술을 사용하고 있는지 모르겠지만 .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 속성에 제공된 사용자 세부 정보를 승인 할 수 있습니다.

당신은 할 수 이미 서명이 다시 공개 키를 포함 할 필요가 없습니다 의미, 공개 키를 가지고 있지만, 당신은 또한 여러 가능한 보내는 사람, 또는 발송인의 체인을 가질 수 있습니다.

예를 들어 신뢰할 수있는 공급자가 두 개있을 수 있습니다. 두 경우 모두 두 공급자를 신뢰하는지 확인하기 전에 메시지가 변조되지 않았는지 확인합니다. 키가 서명에 없으면 어설 션이 조금 더 작을 수 있지만 이제 어설 션이 어떤 ID 공급자에서 왔는지 미리 알아야합니다.

따라서 실제로 공개 키가 서명에있는 두 가지 주요 이유가 있습니다.

  1. 변조 확인은 신원 확인보다 빠르며 공개 키가 알려진 경우 격리 할 수 ​​있습니다.
  2. 키가 어설 션에 있으면 다중 ID를 지원하기가 훨씬 쉽습니다.

2
@svlada SAML 어설 션에는 텍스트 자체가 SSL을 통해 전송 될 수 있으므로 자체 암호화가 필요하지 않습니다. 전체 사용자 세션은 HTTPS 여야합니다. 알려진 신뢰할 수있는 발신자가 어설 션에 서명했으며 변조되지 않았 음을 확인하는 것으로 충분합니다.
Keith

5
@svlada 어떤 종류의 HTTP 기반 인증도 SSL없이 수행해서는 안됩니다. 인증서를 암호화하면 중간자 (MitM)가 읽는 것을 막을 수 있지만 쿠키 기반 MitM 공격과 유사한 방식으로 인증서를 다시 사용하는 것을 막지는 못합니다.
Keith

8
SAML 응답에는 해당 서명에 대한 공개 키를 포함 할 필요 가 없습니다 . SAML2 사양의 섹션 5.4.5에 "XML 서명은 <ds : KeyInfo> 요소의 사용을 정의합니다. SAML은 <ds : KeyInfo>의 사용을 요구하지 않으며 사용에 대한 제한도 부과하지 않습니다. 따라서 <ds : KeyInfo>가 없을 수 있습니다. " SAML 소비자를 구현하기 전에 다른 방법 (예 : 로컬 인증서 저장소에 저장)을 통해 공개 키가 제공된 경우 서명을 확인할 수 있습니다.
Sam Rueby 2014

2
@ Sam.Rueby 아, 내가 정정하겠습니다. 내가 본 모든 구현에는 키가 포함되어 있습니다.
Keith

5
@Jez이 전체 프로토콜은 지옥만큼 혼란 스럽습니다. 기본적으로 어설 션은 자체 포함되어 있습니다. 개인 키가 서명 한 이후로 변경되지 않았는지 확인할 수 있습니다. 공개 키 없이도이 작업을 수행 할 수 있습니다 (그래서이 주장은 Dave로부터 왔으며 Dave가 서명 한 이후 아무도 그것을 조작하지 않았다는 것을 알고 있지만 Dave가 누구인지 또는 내가 그를 믿을 수 있는지는 알 수 없습니다). 그런 다음 확인 후 공개 키가 내가 신뢰하는 키인지 확인할 수 있습니다. 최종 확인이 지연 될 수 있기 때문이라고 생각합니다 (데이브를 아는 사람이 있는지 사무실에 대해 물어 보는 동안)
Keith

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
응답의 인증서가 메타 데이터의 인증서와 일치해야한다는 점이 중요한 점이라고 생각합니다. 그렇지 않으면 원하는 인증서로 응답에 서명하고 확인을 위해 공개 키를 보낼 수 있습니다.
dana

5
나는 이것이 최선의 대답이라고 생각합니다. 다른 사람들은 메시지 자체에 선언 된 키에 대해 메시지를 확인하는 것이 보안을 제공하지 않는다는 점을 놓치고있는 것 같습니다 ... 메시지의 키를 여전히 확인해야합니다 맞다! (이 경우 신뢰할 수있는 메타 데이터에 있는지 확인해야합니다).
rchampourlier

3
위의 의견에 전적으로 동의합니다. 서명의 전체 요점은 메시지가 신뢰할 수 있는지 확인하는 것이기 때문에 메시지에 전달 된 인증서는 그 자체로 는 쓸모 가 없습니다. 메시지가 신뢰할 수없는 경우 번들 인증서도 아닙니다.
Jez

@jbindel-감사합니다! 가능한 경우 newby 질문이 있습니다.이 SAML 인증서가 현재 실제 인증서와 일치해야합니까, 아니면 메타 데이터 일치를 달성하는 데만 사용됩니까? IdP가 인증서 키를 다시 입력하는 것이 운영에 미치는 영향에 대해 우려하기 때문에 이것을 묻습니다.이 시점에서 아마도 메타 데이터 키와 동기화되지 않을 것입니다. 2가 동점이면 다시 걱정됩니다. 운영상의 영향 ie. SP와 IdP가 모두 SAML2 키를 수동으로 업데이트 할 때까지 모든 SSO가 실패하고 불완전한 기술 통신이 SSO 사용자에게 영향을 미칩니다. (어리석은 질문이면 사과)
Pancho

SP 메타 데이터에는 인증서가 포함되어야하지만 SP 메타 데이터는 이전 및 새 IdP 인증서를 모두 지정할 수 있습니다. IdP가 인증서를 업데이트하는 경우 SP 메타 데이터에 추가 할 수 있습니다. IdP가 이전 인증서를 사용하여 완료되면 SP 메타 데이터에서 제거 할 수 있습니다. 그것이 당신이 요구하는 것을 해결합니까? 나는 이것이 Shibboleth SP에서 완벽하게 잘 작동한다는 것을 알고 있습니다. SP 메타 데이터 파일 <KeyDescriptor use="signing">에는 SP에서 수락 할 IdP 인증서에 대한 요소 만 있으면됩니다.
jbindel

8

서명 인증서의 공개 부분은 SAML 메시지에 있습니다. 이것은 토큰 자체의 서명을 확인하고 물론 수신자가 토큰을 발행 한 사람을 알리고 그에 따라 처리 할 수 ​​있도록하는 데 사용됩니다.

그것이 XML 디지털 서명 사양의 일부라는 사실은 실제로 SAML과 관련된 것이 아닙니다. 인증서가 없으면 토큰의 출처를 어떻게 알 수 있으며 어떻게 유효성을 검사 할 수 있습니까?

XmlDSig는 다른 방법을 지정합니다. 주체, 일련 번호, 해시 등으로 서명 키를 식별 할 수 있지만 이는 수신 당사자가 공용 인증서를 가지고 있다고 가정합니다. SAML의 경우 그렇지 않을 수 있으므로 X509 인증서의 공개 부분이 포함됩니다.


1
"인증서없이 토큰이 어디에서 왔는지 어떻게 알 수 있으며 어떻게 검증 할 수 있습니까?" -무슨 소리 야? SAML 메시지의 서명을 신뢰하려면 신뢰할 수있는 공용 인증서 목록이 이미 있어야합니다. Issuer요소를 사용하고 해당 발급자의 인증서를 저장하고이 메시지의 서명을 확인할 인증서를 선택할 수 있습니다.
Jez

2
Jez는 전혀 사실이 아닙니다. CA와 같은 인증서 발급자는 발급하는 개별 인증서를 신뢰하지 않고 모든 인증서의 로컬 복사본을 보관할 필요없이 신뢰할 수 있습니다.
blowdart

3
blowdart는 CA에서 발급 한 다른 유효한 인증서로 서명 된 saml 토큰을 신뢰하고 있음을 의미합니다. 하나를 사는 것은 불가능하지 않습니다! @Jez가 언급 한대로 토큰이 올바른 소스에서 오는지 확인하려면 신뢰할 수있는 공인 인증서 목록이 이미 있어야합니다.
Sun

2
@Sun, 올바르지 않습니다. 이는 Wells Fargo가 동일한 CA를 가지고있는 경우 Bank of America를 가장 할 수 있다고 말하는 것과 같습니다. X509 인증서에는 올바른 ID에 대해 유효성을 검사 할 수있는 주제 DN이 있습니다.
Paul Draper

+1은 특히 이것이 XML 디지털 서명 사양의 일부임을 식별하는 데있어, 거의 모든 SAML 구현이 XML 라이브러리에 의존하여 무거운 짐.
BryKKan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.