2013-05-28 88 views
0

我正在实施SSO作为服务提供商,而ID提供商是RSA FIM又名EMC。我成功地向他们发送AuthN请求并接收saml响应,但我似乎可以验证签名。他们给我发送了他们真实的.cer文件,现在我直接把它拉起来并抓住公钥。然后将其传递给支票签名功能。任何帮助或指针将不胜感激,让我知道是否需要澄清。无论什么时候,我都没有在检查签名方法上得到任何错误。我试着将编码从utf-8更改为ASCII。无济于事似乎工作,我即将发疯!哈哈SAML RSA FIM(EMC)无法验证签名

这是逻辑:被发送

/*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> 

谢谢, 马克

回答

0

我从这里(https://stackoverflow.com/a/6139044/778401)发现我的回答感谢Keith的。使用名称管理器来完成签名节点,并为我提供了一个干净的签名验证。我不得不稍微修改一下,以便签名从响应节点而不是断言节点拉出来,但效果很好。非常感谢Keith!

// 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);