在工作中,我们有一个网络应用程序,我们需要使用SAML验证的单点登录与其他公司的网络应用程序进行交互。我们的网络应用程序是用PHP编写的,显然与其他公司使用的语言选择无关。尽管如此,我还需要编写一个简单的API,这个其他公司可以使用SAML请求发送SOAP请求,并生成SAML响应。我一直在从头开始编写它有三个原因: 1)即使我想要一个用PHP编写的SAML交互也没有很多选项, 2)它限制了添加另一个第三方组件所涉及的开销, 3)从头开始创建事物通常会让我有更好的理解,让我更有能力适应这个事情将来如果需要的话。
无论如何,我对SAML,SOAP和XML标准一般都是新手,所以我一直在教自己。我已经为我们的目的提供了相当完整的API,但有一个例外,即另一家公司已经指定我们的响应将需要使用证书进行数字签名(我们收到的请求将同样进行数字签名)。所以我一直在试图弄清楚如何处理/生成XML签名,但老实说,由于W3C规范并不是轻微的阅读,所以有点令人困惑。
Assertions and Protocol for the OASIS Security Markup Language (SAML) V1.1文件的第5.4.8节(我已经关闭的文件,正如另一家公司所说他们将使用v1.1)包含一个包含已签名断言的签名响应的示例,我将在此处参考:
<Response IssueInstant="2003-04-17T00:46:02Z" MajorVersion="1" MinorVersion="1"
Recipient="www.opensaml.org" ResponseID="_c7055387-af61-4fce-8b98-e2927324b306"
xmlns="urn:oasis:names:tc:SAML:1.0:protocol"
xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#_c7055387-af61-4fce-8b98-e2927324b306">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<InclusiveNamespaces PrefixList="#default saml samlp ds xsd xsi"
xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>TCDVSuG6grhyHbzhQFWFzGrxIPE=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>x/GyPbzmFEe85pGD3c1aXG4Vspb9V9jGCjwcRCKrtwPS6vdVNCcY5rHaFPYWkf+5EIYcPzx+pX1h43SmwviCqXRjRtMANWbHLhWAptaK1ywS7gFgsD01qjyen3CP+m3Dw6vKhaq1ed10BYyrIzb4KkHO4ahNyBVXbJwqv5pUaE4=</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIICyjCCAjOgAwIBAgICAnUwDQYJKoZIhvcNAQEEBQAwgakxCzAJBgNVBAYTA1VT ... 8I3bsbmRAUg4UP9hH6ABVq4KQKMknxu1xQxLhpR1y1GPdiowMNTrEG8cCx3w/w==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<Status><StatusCode Value="samlp:Success"/></Status>
<Assertion AssertionID="_a75adf55-01d7-40cc-929f-dbd8372ebdfc"
IssueInstant="2003-04-17T00:46:02Z" Issuer="www.opensaml.org"
MajorVersion="1" MinorVersion="1" xmlns="urn:oasis:names:tc:SAML:1.0:assertion"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Conditions NotBefore="2003-04-17T00:46:02Z" NotOnOrAfter="2003-04-17T00:51:02Z">
<AudienceRestrictionCondition>
<Audience>http://www.opensaml.org</Audience>
</AudienceRestrictionCondition>
</Conditions>
<AuthenticationStatement AuthenticationInstant="2003-04-17T00:46:00Z"
AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password">
<Subject>
<NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">scott@example.org</NameIdentifier>
<SubjectConfirmation>
<ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</ConfirmationMethod>
</SubjectConfirmation>
</Subject>
<SubjectLocality IPAddress="127.0.0.1"/>
</AuthenticationStatement>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#_a75adf55-01d7-40cc-929f-dbd8372ebdfc">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<InclusiveNamespaces PrefixList="#default saml samlp ds xsd xsi"
xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>Kclet6XcaOgOWXM4gty6/UNdviI=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>hq4zk+ZknjggCQgZm7ea8fI79gJEsRy3E8LHDpYXWQIgZpkJN9CMLG8ENR4Nrw+n7iyzixBvKXX8P53BTCT4VghPBWhFTSt9tHWu/AtJfOTh6qaAsNdeCyG86jmtp3TDMWuL/cBUj2OtBZOQMFn7jQ9YB7k1Iz3RqVL+wNmeWI4=</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIICyjCCAjOgAwIBAgICAnUwDQYJKoZIhvcNAQEEBQAwgakxCzAJBgNVBAYTA1VT ... 8I3bsbmRAUg4UP9hH6ABVq4KQKMknxu1xQxLhpR1y1GPdiowMNTrEG8cCx3w/w==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</Assertion>
</Response>
那么如何生成这样的东西呢?如果我收到这样的东西,我该如何验证呢?此外,任何人都可以提供<ds:Signature>
标签在这里的基本概念概述吗?似乎有两个<ds:Signature>
标记,一个在主<Response>
中,一个在<Assertion>
中,每个都包含自己的<ds:DigestValue>
,<ds:SignatureValue>
和{{ 1}}(和每个不同的)。这些是如何产生的?任何你可以在这上面的光都将非常感激。教程或代码示例将更加受到重视!但在这一点上,如果你能让我走上正轨,那就是我真正想要的。现在它对我来说似乎仍然是一个大黑盒子。
顺便说一句,如果这有帮助,它在SAML 1.1规范的其他地方说SAML实现应该只使用“Exclusive Canonicalization”方法(Excl-C14N),并且应该只使用“包络变换”。我还不完全确定这意味着什么。
答案 0 :(得分:29)
如果您非常熟悉XML,处理XML签名并不是很难,但是有很多细节必须绝对正确或者事情不起作用,所以我可能不会尝试编写自己的在这种情况下的实现(我确实部分实现了一次,但这是为了一个不同的和特殊的目的,无论如何它不是一个完整的实现)。
无论如何,我对SAML知之甚少,但我确实知道XML和XML签名,所以也许我可以通过尝试回答你的问题来帮助你。
Signature
元素是指在SignedInfo
子元素中经过数字签名的XML文档的特定部分。 Reference
子元素(我认为可以有很多Reference
个元素在形成要签名的字节时连接但我不记得确定了)通过{指向内容{1}}属性。 URI
元素描述在对其进行散列之前对引用内容执行的转换;您需要查看规范以确定如何定义转换算法。 Transform
元素将哈希算法应用于作为这些转换算法结果的字节(请注意,其中一个始终是将XML转换为字节的规范化),DigestMethod
给出结果该摘要算法。
实际签名位于DigestValue
元素中,并通过应用SignatureValue
元素的规范化来生成字节,然后使用CanonicalizationMethod
对这些字节进行签名来生成。 SignatureMethod
元素告诉您如何找到要使用的密钥。
Canonicalization,在上面出现过两次,只是将XML文档转换为字节的一种方式,以便“等效”的XML文档产生相同的字节序列。这在数字签名中是必需的,因为算法在字节上工作,XML可以通过许多中介,这些中介可能会破坏原始字节,但会保留等价。不同情况下需要不同的规范化方法:如果元素是从文档中提取并放入其他元素中,则需要排除不需要的命名空间定义的独占规范化,但在其他情况下可能无法正常工作,因此需要包含规范化,保留所有范围内的命名空间。
这只是基础知识。如何生成XML签名有许多不同的选项,如果要实现工作验证程序,则需要考虑所有这些选项。由于您不熟悉XML,我只想重复一下使用已存在的东西的建议。实现规范是一种有趣的学习体验,但如果实现已经可用,通常会浪费时间。
有关于签名的W3C documentation。
答案 1 :(得分:2)
SimpleSAML中的xmlseclibs.php中有一个示例。它依赖于openssl模块来进行加密。
我会诚实地使用lib或者桥接到java / tomcat,只是因为可能会出现可能需要调试的互操作问题,
答案 2 :(得分:0)
您可以查看此Java lib以签署SAML请求示例https://github.com/jrowny/java-saml
要验证签名,您需要安装SAML跟踪器插件https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/
您可以使用工具https://www.samltool.com/validate_logout_req.php对请求进行授权或签名https://www.samltool.com/sign_logout_req.php