从C#验证java SAML签名

时间:2009-09-17 07:03:41

标签: .net saml interop

如何在.Net C#中验证用Java创建的SAML签名? 这是我从Java获得的SAML签名:

  <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:CanonicalizationMethod>
        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1">
        </ds:SignatureMethod>
        <ds:Reference URI="#_e8bcba9d1c76d128938bddd5ae8c68e1">
            <ds:Transforms>
                <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
                </ds:Transform>
                <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                    <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="code ds kind rw saml samlp typens #default xsd xsi">
                    </ec:InclusiveNamespaces>
                </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
            </ds:DigestMethod>
            <ds:DigestValue>zEL7mB0Wkl+LtjMViO1imbucXiE=</ds:DigestValue>
        </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>
jpIX3WbX9SCFnqrpDyLj4TeJN5DGIvlEH+o/mb9M01VGdgFRLtfHqIm16BloApUPg2dDafmc9DwL
Pyvs3TJ/hi0Q8f0ucaKdIuw+gBGxWFMcj/U68ZuLiv7U+Qe7i4ZA33rWPorkE82yfMacGf6ropPt
v73mC0bpBP1ubo5qbM4=
    </ds:SignatureValue>
    <ds:KeyInfo>
        <ds:X509Data>
            <ds:X509Certificate>
MIIDBDCCAeygAwIBAgIIC/ktBs1lgYcwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UEAwwIQWRtaW5D
QTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0UwHhcNMDkwMjIzMTAwMzEzWhcN
MTgxMDE1MDkyNTQyWjBaMRQwEgYDVQQDDAsxMC41NS40MC42MTEbMBkGA1UECwwST24gRGVtYW5k
IFBsYXRmb3JtMRIwEAYDVQQLDAlPbiBEZW1hbmQxETAPBgNVBAsMCFNvZnR3YXJlMIGfMA0GCSqG
SIb3DQEBAQUAA4GNADCBiQKBgQCk5EqiedxA6WEE9N2vegSCqleFpXMfGplkrcPOdXTRLLOuRgQJ
LEsOaqspDFoqk7yJgr7kaQROjB9OicSH7Hhsu7HbdD6N3ntwQYoeNZ8nvLSSx4jz21zvswxAqw1p
DoGl3J6hks5owL4eYs2yRHvqgqXyZoxCccYwc4fYzMi42wIDAQABo3UwczAdBgNVHQ4EFgQUkrpk
yryZToKXOXuiU2hNsKXLbyIwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSiviFUK7DUsjvByMfK
g+pm4b2s7DAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQEF
BQADggEBAKb94tnK2obEyvw8ZJ87u7gvkMxIezpBi/SqXTEBK1by0NHs8VJmdDN9+aOvC5np4fOL
fFcRH++n6fvemEGgIkK3pOmNL5WiPpbWxrx55Yqwnr6eLsbdATALE4cgyZWHl/E0uVO2Ixlqeygw
XTfg450cCWj4yfPTVZ73raKaDTWZK/Tnt7+ulm8xN+YWUIIbtW3KBQbGomqOzpftALyIKLVtBq7L
J0hgsKGHNUnssWj5dt3bYrHgzaWLlpW3ikdRd67Nf0c1zOEgKHNEozrtRKiLLy+3bIiFk0CHImac
1zeqLlhjrG3OmIsIjxc1Vbc0+E+z6Unco474oSGf+D1DO+Y=

            </ds:X509Certificate>
        </ds:X509Data>
    </ds:KeyInfo>
</ds:Signature>

我知道解析SAML,我需要验证签名。 我试过这个:

public bool VerifySignature()
{
    X509Certificate2 certificate = null;

    XmlDocument doc = new XmlDocument();
    XmlElement xmlAssertionElement = this.GetXml(doc);
    doc.AppendChild(xmlAssertionElement);

    // Create a new SignedXml object and pass it
    // the XML document class.
    SamlSignedXml signedXml = new SamlSignedXml(xmlAssertionElement);

    // Get signature
    XmlElement xmlSignature = this.Signature;
    if (xmlSignature == null)
    {
        return false;
    }

    // Load the signature node.
    signedXml.LoadXml(xmlSignature);

    // Get the certificate used to sign the assertion if information about this 
    // certificate is available in the signature of the assertion.
    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)
    {
        return false;
    }

    return signedXml.CheckSignature(certificate, true);
  }

验证在.Net中签名的SAML的签名,但不验证此Java签名。

2 个答案:

答案 0 :(得分:5)

用这个帖子中的答案解决了问题: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/faf0b66c-294b-4d84-a19b-504dd8e81922 我的代码与MSDN中显示的示例非常相似,只缺少的是: 验证时doc.PreserveWhitespace = true。

答案 1 :(得分:0)

只要您在证书库中拥有公钥,就可以使用System.Security.Cryptography.Xml命名空间中的类来验证使用数字签名签名的XML数据。我已经做了一些工作,一段时间后AD联盟服务也使用SAML,我记得在找到我需要的命名空间后,剩下的就相当简单了 - 但是很久以前,细节让我感到厌烦。