SAML:为什么签名中的证书?

我必须使用SAML为我公司的网站(作为依赖方)实施SSO。 一个关键的部分是validation签名。 以下是来自我们合作伙伴公司(断言方)的示例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> 

我只是不明白,为什么在签名内的证书?

我的意思是通常我会以安全的方式获得公司的证书,所以我知道证书是来自他们的。 而且当签名validation成功时,我知道我们的合作伙伴公司已经签署了。

但是,当证书在SAML-Response的签名中时,任何人都可以发送它! 我唯一知道的是答复没有被证伪。 但重要的是,我不知道是谁发送了SAML。

任何人都可以向我解释,这是如何工作的?

SAML响应带有该签名的签名和公钥。

您可以使用公钥来validationSAML响应的内容是否与密钥匹配 – 换句话说,这个响应肯定来自某个与私钥具有相同私钥的人,并且响应还没有篡改。

我不知道你在用什么技术,但在.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); 

这只是检查消息来自谁说的。 您需要额外检查邮件是否来自您信任的人,而且此检查速度较慢 – 需要包含吊销,并且可能需要validation整个证书链。

通常,这将是您接受SAML响应的公钥列表。

然后,您可以检查此消息是否已被篡改,并且来自您信任的人,因此您可以授权提供的SAML属性中提供的用户详细信息。

可能已经拥有了公钥,这意味着签名不需要再次包含公钥,但是您也可以有多个可能的已知发件人,甚至已知的发件人链。

例如,您可能有两个可信任的提供者 – 无论是哪种情况,都要在检查您是否信任提供者之前检查该消息是否已被篡改。 如果密钥不在签名中,断言可能会稍微小一些,但是现在您必须事先知道断言来自哪个身份提供者。

所以,真的有两个主要原因是公钥在签名中:

  1. 篡改检查比身份检查快,如果公钥已知,则可以隔离。
  2. 如果关键是在断言中,多个身份更容易支持。

指定密钥的原因是身份提供者的元数据可以指定多个签名密钥,并且可以通过将其包含在签名中来指定要使用的密钥。 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系统在validation签名时必须生成错误。

签名证书的公共部分在SAML消息中。 这用于检查令牌本身的签名,当然也可以让接收者知道发出令牌的人是谁,并相应地对待它。

XML数字签名规范的一部分,它不是SAML特有的。 没有证书,你怎么知道令牌是从哪里来的?你怎么能validation它呢?

XmlDSig指定了其他方法,可以通过主题,序列号,哈希等来标识签名密钥,但是这里假设接收方拥有公共证书。 对于SAML,情况可能并非如此,因此embedded了X509证书的公共部分。

发布相当晚,但我不得不在SAML上工作,发现这些文件。 他们对SAML提供了一个很好的见解 – 它是如何工作的以及它期望的参数。 应该为SAML的新人提供一些帮助。

http://developers.onelogin.com/v1.0/page/intro-to-onelogins-open-source-saml-toolkits

http://developers.onelogin.com/v1.0/page/saml-toolkit-for-ruby-on-rails