验证C#中的Java SAML响应#

问题描述:

我在查看围绕C#中的Java生成的SAML响应验证的各种帖子。我一直在尝试所有的建议,并且仍然从SignedXml.CheckSignature中得到一个错误,现在完全没有关于什么可能是错误的想法,并且正在向你们询问是否有我可以使用的建议。验证C#中的Java 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="#SM16afb708b851b15451d92108ac8c6a2a627a2643667" 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#"/> 
    </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#">kOlL02M8icLI1MtFnFUAcf/yols=</ds:DigestValue> 
    </ds:Reference> 
    </ds:SignedInfo> 
    <ds:SignatureValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    d2wjnwPdzDrsWvMq9EElkb0TVsj8LmMXqTusPuG3GbxsqVLFryqaMkwv/whTYD/evw8WNClJm1nC 
    VpGTEPEB/voPiFJaNpdwvs6a6PuTizLQQaqOC1H6JC6KboUVR87wuJ4kV3W9QoGEft+OmZXMgUU6 
    54PgOX3d/czqlQWS9Z8= 
    </ds:SignatureValue> 
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    <ds:X509Data xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    <ds:X509Certificate xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    MIICCjCCAXOgAwIBAgIQazR4XEyfFItIKZvB/IC3/jANBgkqhkiG9w0BAQQFADATMREwDwYDVQQD 
    EwhTYW1sVGVzdDAgFw0wMDAxMDEwNDAwMDBaGA8yMDk5MDEwMTA0MDAwMFowEzERMA8GA1UEAxMI 
    U2FtbFRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAK4kfW9Jg/WtQ+4yy631r2qkCVyK 
    odGL0A3lg+4w3BfCSGf4N7GkAlHI4G582tC4tlwd/mj/IvN6qxhIyu45OlENZhWOXFOCogoX7Tfx 
    Vd7XRUqNwdndjy9KY7uyIrXVczpGbk+ahp6SS0NAG9i1rYR/pxTvW4zUHkrFbgm8gdghAgMBAAGj 
    XTBbMBMGA1UdJQQMMAoGCCsGAQUFBwMDMEQGA1UdAQQ9MDuAEHITUeo8fKKVys7DcdV65hmhFTAT 
    MREwDwYDVQQDEwhTYW1sVGVzdIIQazR4XEyfFItIKZvB/IC3/jANBgkqhkiG9w0BAQQFAAOBgQA/ 
    Dm+yk4K3q8AG3q4dorWswL8fwU9dpjuvheRjAveaL5kr59QRanG+lLi8Wefg6iTPKDgIGc2VG13T 
    KP7pZSysaXJ5i8N0zCg+eu/YL7Hw1kSXW/CdxwQ+qI1W53fQ9NXlLVWPXhIepAOL46EEZgACHEhv 
    tG30XtStycyLOsgm9A== 
    </ds:X509Certificate> 
    </ds:X509Data> 
    </ds:KeyInfo> 
</ds:Signature> 

,我使用验证响应的C#代码是

try 
{ 
    XmlDocument xmlDoc = new XmlDocument(); 
    xmlDoc.PreserveWhitespace = true; 
    xmlDoc.Load(@"C:\SAMLSSOResponse.txt"); 

    XmlNamespaceManager _documentNamespaceManager; 
    _documentNamespaceManager = new XmlNamespaceManager(xmlDoc.NameTable); 
    _documentNamespaceManager.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#"); 
    _documentNamespaceManager.AddNamespace("samlp", "urn:oasis:names:tc:SAML:1.0:protocol"); 
    _documentNamespaceManager.AddNamespace("saml", "urn:oasis:names:tc:SAML:1.0:assertion"); 

    SignedXml signedXml = new SignedXml(xmlDoc); 
    XmlNodeList nodeList = xmlDoc.GetElementsByTagName("ds:Signature"); 

    XmlNode xmlNode = xmlDoc.DocumentElement.SelectSingleNode("/samlp:Response/ds:Signature", _documentNamespaceManager); 
    //xmlDoc.GetElementsByTagName("Signature"); 
    //signedXml.LoadXml((XmlElement)xmlNode); 
    signedXml.LoadXml((XmlElement)nodeList[0]); 

    X509Certificate2 certificate = null; 
    foreach (KeyInfoClause clause in signedXml.KeyInfo) 
    { 
     if (clause is KeyInfoX509Data) 
     { 
      if (((KeyInfoX509Data)clause).Certificates.Count > 0) 
      { 
       certificate = (X509Certificate2)((KeyInfoX509Data)clause).Certificates[0]; 
      } 
     } 
    } 

    if (certificate == null) 
    { 
     Console.WriteLine("No Certificate found"); 
    } 

    Console.WriteLine("Testing with Certificate in the XML"); 
    if (signedXml.CheckSignature(certificate, true)) 
     Console.WriteLine("Validated"); 
    else 
     Console.WriteLine("Failed"); 
} 
catch (Exception ex) 
{ 
} 

我甚至尝试通过加载证书验证签名代码,仍然有同样的问题。

任何人有任何建议,为什么签名没有得到验证?

我解决了这个问题。有多个问题,我不得不处理:

  1. 我正在处理的反应是一个字符串,我并没有验证。当我得到Base64Encoded字符串,然后尝试验证它给了我一个不同的错误(格式错误的参考元素),这是通过步骤2解决。

  2. 格式错误的参考元素问题已解决通过创建一个新的类继承自SignedXML然后覆盖GetIdElement类。下面是该代码:

 
public class SamlSignedXml : SignedXml 
    { 
     private string _referenceAttributeId = ""; 
     public SamlSignedXml(XmlElement element, string referenceAttributeId) 
      : base(element) 
     { 
      _referenceAttributeId = referenceAttributeId; 
     } 
     public override XmlElement GetIdElement(
      XmlDocument document, string idValue) 
     { 
      return (XmlElement) 
       document.SelectSingleNode(
        string.Format("//*[@{0}='{1}']", 
        _referenceAttributeId, idValue)); 
     } 
    } 

而且当你创建SamlSignedXml类的实例,你做如下: SamlSignedXml signedXml =新SamlSignedXml(元素, “ResponseID”);

其中element是XmlDocument.DocumentElement。

解决了问题