验证SAML断言签名 [英] Verify signature on SAML assertion

查看:3274
本文介绍了验证SAML断言签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个特征,一个是关于响应(其中验证),一个在嵌套SAML断言(不)。这是冷凝代码我的工作:



<预类=郎-CS prettyprint-覆盖> 的foreach(XmlElement的在xmlDoc.SelectNodes节点(// * [本地名称()='签名']))
{//验证此签名块
SignedXml signedXml =新SignedXml(node.ParentNode作为的XmlElement);
signedXml.LoadXml(节点);
KeyInfoX509Data x509Data = signedXml.Signature.KeyInfo.OfType&所述; KeyInfoX509Data方式>()第一();

//验证证书
X509Certificate2证书= x509Data.Certificates [0]作为X509Certificate2;
log.Info(的String.Format(证书S / N:{0},cert.SerialNumber));
VerifyX509Chain(CERT); //自定义的方法

//检查审批
的X509Store店=新的X509Store(StoreName.TrustedPublisher,StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection集合= store.Certificates.Find(X509FindType.FindBySerialNumber,cert.SerialNumber,真正的);
Debug.Assert的(collection.Count == 1); //站在为简洁

//验证签名
signedXml.CheckSignature(证书,真);
}

有关完整性,这里的XML大纲:



<预类=郎咸平的XML prettyprint-覆盖> < samlp2:响应目标=http://www.testhabaGoba.comID =ResponseId_934151edfe060ceec3067670c2f0f1eaIssueInstant = 2013-09-24T14:33:29.507Z版本=2.0的xmlns:SAML2 =瓮:绿洲:名称:TC:SAML:2.0:断言的xmlns:samlp2 =瓮:绿洲:名称:TC:SAML :2.0:协议>

< DS:签名的xmlns:DS =http://www.w3.org/2000/09/xmldsig#>

< / DS:签字>

< SAML2:断言ID =SamlAssertion-05fd8af7f2c9972e69cdbca612d3f3b8IssueInstant =2013-09-24T14:33:29.496Z版本=2.0的xmlns:SAML2 =瓮:绿洲:名称:TC:SAML:2.0:断言>

< DS:签名的xmlns:DS =http://www.w3.org/2000/09/xmldsig#>

< / DS:签字>

< / SAML2:断言>
< / samlp2:响应>



我也试着只用断言签名,失败也是如此。我究竟做错了什么?为什么 CheckSignature 总是失败的SAML断言?



修改
原来是Java的产生(OpenSAML)一个与刚刚签署的说法,有更多的箍通过跳跃。请指教。


解决方案

我发现的这个答案其引用的另一个答案(由一样的家伙)和款项以下内容: .NET 实施离奇和签名块必须在 DocumentElement 找到的这篇文章这也解决了一个更好的办法的问题时失败。



修改代码



<预类=郎-CS prettyprint-覆盖> 的foreach(在xmlDoc中的XmlElement节点.SelectNodes(// * [本地名称()='签名']))
{//验证此签名块
// *** BEGIN:添加的代码***
XmlDocument的DOC =新的XmlDocument();
doc.LoadXml(node.ParentNode.OuterXml);
XmlElement的签名= doc.SelectSingleNode(// * [本地名称()='签名'])作为XmlElement的;
//这个变量^^^是一样的节点,只需在文档,而不是xmlDoc中(很重要的区别)
// *** END:添加的代码***

//设置
SignedXml signedXml =新SignedXml(node.ParentNode作为的XmlElement);
signedXml.LoadXml(节点);
KeyInfoX509Data x509Data = signedXml.Signature.KeyInfo.OfType&所述; KeyInfoX509Data方式>()第一();

//验证证书
...



不幸的是这还没有考虑Java的生成SAML。一些更复杂的,甚至少有记载,需要考虑到这一点。我收到一个新的Java生成的SAML令牌与给定的代码工作。我用的是一个人必须已经有缺陷的。


I have two signatures, one on the response (which verifies) and one on the nested SAML assertion (which does not). This is the condensed code I'm working with:

foreach (XmlElement node in xmlDoc.SelectNodes("//*[local-name()='Signature']"))
{// Verify this Signature block
    SignedXml signedXml = new SignedXml(node.ParentNode as XmlElement);
    signedXml.LoadXml(node);
    KeyInfoX509Data x509Data = signedXml.Signature.KeyInfo.OfType<KeyInfoX509Data>().First();

    // Verify certificate
    X509Certificate2 cert = x509Data.Certificates[0] as X509Certificate2;
    log.Info(string.Format("Cert s/n: {0}", cert.SerialNumber));
    VerifyX509Chain(cert);// Custom method

    // Check for approval
    X509Store store = new X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine);
    store.Open(OpenFlags.ReadOnly);
    X509Certificate2Collection collection = store.Certificates.Find(X509FindType.FindBySerialNumber, cert.SerialNumber, true);
    Debug.Assert(collection.Count == 1);// Standing in for brevity

    // Verify signature
    signedXml.CheckSignature(cert, true);
}

For completeness, here's an outline of the XML:

<samlp2:Response Destination="http://www.testhabaGoba.com" ID="ResponseId_934151edfe060ceec3067670c2f0f1ea" IssueInstant="2013-09-24T14:33:29.507Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp2="urn:oasis:names:tc:SAML:2.0:protocol">
    ...
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        ...
    </ds:Signature>
    ...
    <saml2:Assertion ID="SamlAssertion-05fd8af7f2c9972e69cdbca612d3f3b8" IssueInstant="2013-09-24T14:33:29.496Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
        ...
        <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            ...
        </ds:Signature>
        ...
    </saml2:Assertion>
</samlp2:Response>

I've also tried with just the assertion signed, and that fails as well. What am I doing wrong? Why does CheckSignature always fail on the SAML assertion?

Edit Turns out the one with just the assertion signed is Java-generated (OpenSAML) and has more hoops to jump through. Please advise.

解决方案

I found this answer which references another answer (by the same guy) and sums to the following: The implementation is quirky and the Signature block must be a child of the DocumentElement. Found this article which also solved the problem in a better way.

Modified Code

foreach (XmlElement node in xmlDoc.SelectNodes("//*[local-name()='Signature']"))
{// Verify this Signature block
    // *** BEGIN: ADDED CODE ***
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(node.ParentNode.OuterXml);
    XmlElement signature = doc.SelectSingleNode("//*[local-name()='Signature']") as XmlElement;
    // This variable ^^^ is the same as node, just in doc instead of xmlDoc (important distinction)
    // *** END: ADDED CODE ***

    // Setup
    SignedXml signedXml = new SignedXml(node.ParentNode as XmlElement);
    signedXml.LoadXml(node);
    KeyInfoX509Data x509Data = signedXml.Signature.KeyInfo.OfType<KeyInfoX509Data>().First();

    // Verify certificate
    ...

Unfortunately this still doesn't account for Java-generated SAML. Something more intricate and even less documented is required to account for that. I received a new Java-generated SAML token that works with the given code. The one I was using must have been defective.

这篇关于验证SAML断言签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆