0

我将 SSO 实施为服务提供商,ID 提供商是 RSA FIM aka EMC。我成功地向他们发送了一个 AuthN 请求并收到了一个 saml 响应,但我似乎可以验证签名。他们已经向我发送了他们实际的 .cer 文件,目前我直接将其拉出并获取公钥。然后将其传递给检查签名函数。任何帮助或指示将不胜感激,如果需要任何澄清,请告诉我。无论如何,我每次都没有收到任何错误,只是检查签名方法的错误。我尝试将编码从 utf-8 更改为 ASCII。无济于事似乎没有任何工作,我要疯了!哈哈

这是逻辑:

/*Get XML in previous function and build saml doc.*/

byte[] base64EncodedBytes = Convert.FromBase64String(samlResponse);
samlXml = System.Text.Encoding.UTF8.GetString(base64EncodedBytes); 

_SamlDocument = new XmlDocument();
_SamlDocument.PreserveWhitespace = true;
_SamlDocument.LoadXml(samlXml);


/*Verify Function*/
        public Boolean Verify()
        {
            // Check arguments.
            if (_SamlDocument == null)
                throw new ArgumentException("Invalid XML Doc.");

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

            XmlNamespaceManager manager = new XmlNamespaceManager(_SamlDocument.NameTable);
            manager.AddNamespace("ds", SamlSignedXml.XmlDsigNamespaceUrl);

            // Find the "Signature" node and create a new
            // XmlNodeList object.
            XmlNodeList nodeList =  _SamlDocument.SelectNodes("//ds:Signature", manager);

            // Throw an exception if no signature was found.
            if (nodeList.Count <= 0)
            {
                throw new CryptographicException("Verification failed: No Signature was found in the document.");
            }

            // This example only supports one signature for
            // the entire XML document.  Throw an exception
            // if more than one signature was found.
            if (nodeList.Count >= 2)
            {
                throw new CryptographicException("Verification failed: More that one signature was found for the document.");
            }

            // Load the first <signature> node.
            signedXml.LoadXml((XmlElement)nodeList[0]);

            var bVerified = false;

            /*Pulls in .cer file directly from brand cert string which is a file location.*/
            X509Certificate2 brandCert = new X509Certificate2(brandCertificateString);
            bVerified = signedXml.CheckSignature(brandCert.PublicKey.Key);

            return bVerified;
        }

/发送的样本 saml 响应。/

<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" Destination="_removed information_" ID="c9c96cd8c3e6cdef4d5c1d976968d347" InResponseTo="_5990ada8-e69f-4e66-90f1-d7e96dafbe4f" IssueInstant="2013-05-23T18:52:24Z" Version="2.0"><saml:Issuer>_removed information_</saml:Issuer><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="#c9c96cd8c3e6cdef4d5c1d976968d347">
<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#"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>Bi9EXd/yvWKHV7Hvc8tB3ddmDW8=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
eCwiyItypMUOW9dUs8nEx5ufKRZfwCcDKTvkEYa4UQA048N9Sno4/tPJICenhV/5SCjnMSR4wx5q
FKcS5FiMK0q1JFl3qeDzUwl1zH1kqJQjS1fUatC7SKvCRRAI25nNapGT/4DZiaTmEt3tzf/o36b0
HHyuLkFI3RlaEtzJ91vE7uH5dOI6GPAaG9p8rtBDXvNWhsGnuYIaJog8MUUXuD3wAudNAhMvuBsq
rjsR0GW4x92k60lbMcus+qHNtpZyT96LyKVW5MF9HklQOkEW0ip8AJD3u6n3RTAtQnmoIJIOzSzH
15pnmOJJVWzD7UqnWjAZIjWR7NYiDBSpggYtvA==
</ds:SignatureValue>
</ds:Signature><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode></samlp:Status><saml:Assertion ID="d26d141cea5a9a5c912916a534957e04" IssueInstant="2013-05-23T18:52:24Z" Version="2.0"><saml:Issuer>_removedinformation_</saml:Issuer><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">_removed information_</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="_5990ada8-e69f-4e66-90f1-d7e96dafbe4f" NotOnOrAfter="2013-05-23T18:53:24Z" Recipient="_removed information_"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2013-05-23T18:51:54Z" NotOnOrAfter="2013-05-23T18:53:24Z"><saml:AudienceRestriction><saml:Audience>_removed information_</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2013-05-23T18:52:23Z" SessionIndex="d26d141cea5a9a5c912916a534957e04"><saml:SubjectLocality Address="10.96.40.30" DNSName="localhost.localdomain"></saml:SubjectLocality><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><saml:Attribute FriendlyName="UserName" Name="UserName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xsi:type="xs:string">_removed information_</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></samlp:Response>

谢谢,马克

4

1 回答 1

0

感谢 Keith 从这里( https://stackoverflow.com/a/6139044/778401 )找到我的答案。使用名称管理器深入到签名节点工作得很好,让我得到了一个干净的签名验证。我不得不稍作修改,以便从响应节点而不是断言节点中提取签名,但它工作得很好。非常感谢基思!

// 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);
于 2013-06-03T19:49:40.770 回答