SAML:証明書が署名内にあるのはなぜですか?


103

私の会社のWebサイト(証明書利用者として)に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属性で提供されたユーザーの詳細を承認できます。

あなたは可能性が既に署名が再び公開鍵を含める必要がないことを意味し、公開鍵を持っていますが、あなたはまた、複数の可能な既知の送信者、あるいは知られている送信者のチェーンを持つことができます。

たとえば、2つの信頼できるプロバイダーがあるとします。どちらの場合も、どちらかのプロバイダーを信頼するかどうかを確認する前に、メッセージが改ざんされていないことを確認します。キーが署名に含まれていない場合、アサーションは少し小さくなる可能性がありますが、アサーションの送信元のIDプロバイダーを事前に知る必要があります。

したがって、実際には、公開鍵が署名に含まれている主な理由は2つあります。

  1. 改ざんチェックはIDチェックよりも速く、公開鍵がわかっている場合は分離できます。
  2. キーがアサーションにある場合、複数のIDをサポートする方がはるかに簡単です。

2
@svladaテキスト自体はSSL経由で送信できるため、SAMLアサーションは独自の暗号化を必要としません。ユーザーセッション全体はHTTPSである必要があります。既知の信頼できる送信者がアサーションに署名し、改ざんされていないことを確認すれば十分です。
キース、

5
@svlada HTTPベースの認証(あらゆる種類の)は、SSLなしでは決して行われるべきではありません。証明書を暗号化すると、中間者(MitM)がそれを読み取ることができなくなりますが、CookieベースのMitM攻撃と同様の方法で証明書を再利用することはできます。
キース

8
SAML応答には、その署名の公開鍵を含める必要ありませ。SAML2仕様のセクション5.4.5には、「XML署名は<ds:KeyInfo>要素の使用を定義します。SAMLは<ds:KeyInfo>の使用を必要とせず、その使用に制限を課しません。したがって、<ds :KeyInfo>が存在しない場合があります。」SAMLコンシューマを実装する前にローカル証明書ストアに格納されているなど、他の方法で公開鍵が提供されている場合は、署名を検証できます。
Sam Rueby 2014年

2
@ Sam.Ruebyああ、私はそれを修正します。私が見たすべての実装にはキーが含まれています。
キース

5
@Jezこのプロトコル全体は地獄と同じくらい混乱しています。基本的に、アサーションは自己完結型です。秘密鍵で署名されてから改ざんされていないことを確認できます。あなたはその公開鍵を自分で持っていなくてもこれを行うことができます(つまり、このアサーションがDaveからのものであり、Daveが署名してからだれもそれを改ざんしていないことを知っていますが、Daveが誰であるか、または私が彼を信頼できるかどうかはわかりません)。次に、それを確認した後、公開鍵が信頼できるものであることを確認できます。これは、その最終チェックに遅延がある可能性があるためだと思います(オフィスに誰かがデイブを知っているかどうか尋ねている間)
キース

41

キーが指定されている理由は、IDプロバイダーのメタデータで複数の署名キーを指定できることと、署名に含めることで使用するキーを指定できることです。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
これが最良の答えだと思います。他の人はメッセージ自体で宣言されたキーに対してメッセージをチェックしてもセキュリティが得られないという点を見落としているようです...メッセージのキーをチェックする必要がありますは正しい!(この場合、それが信頼できるメタデータにあることを確認する必要があります)。
シャンポンリエ2015年

3
上記のコメントに完全に同意します。メッセージで渡される証明書は、それ自体では価値がありません。署名の目的は、メッセージが信頼できることを確認することです。メッセージが信頼できない場合は、バンドルされた証明書も信頼できません。
Jez

@jbindel-ありがとうございます!可能であればnewbyの質問があります。このSAML証明書は現在の物理証明書と一致する必要がありますか、それともメタデータの一致を達成するためだけに使用されますか?IdPが証明書のキーを再生成することの運用上の影響を懸念しているので、これを質問します。その時点で、おそらくメタデータキーと同期しなくなります。2が同点の場合、私は再懸念しています。運用上の影響、つまり SPとIdPの両方がSAML2キーを手動で更新するまで、すべてのSSOが失敗し、技術的なコミュニケーションが不完全な場合にSSOユーザーに影響が及ぶことに注意してください。(愚かな質問の場合は謝罪)
パンチョ

SPメタデータには証明書を含める必要がありますが、SPメタデータは古いIdP証明書と新しい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 2015

2
すべてのジェズには当てはまりません。CAなどの証明書発行者は、発行する個々の証明書を信頼したり、すべての証明書のローカルコピーを保持したりすることなく、信頼できます。
blowdart 2015

3
これは、CAが発行した他の有効な証明書によって署名されたsamlトークンを信頼していることを意味します。購入することは不可能ではありません!@Jezが述べたように、トークンが正しいソースからのものであることを確認するには、信頼できるパブリック証明書のリストがすでにあるはずです。

2
@Sun、不正解。同じCAがあれば、ウェルズファーゴはバンクオブアメリカになりすますことができると言っているようなものです。X509証明書には、正しいIDを検証できるサブジェクトDNがあります。
Paul Draper

+1は、これがXMLデジタル署名仕様の一部であることを識別するために特に重要です。初心者にはそれほど明白ではなく、メッセージが実際に処理される方法を理解するために重要です。ほとんどすべてのSAML実装は、XMLライブラリに依存して重い物を持ち上げる。
BryKKan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.