C# SAML RSA FIM(EMC)无法验证签名
我作为服务提供商实施SSO,ID提供商是RSA FIM,又称EMC。我成功地向他们发送了一个AuthN请求并收到了一个saml响应,但我似乎只是验证了签名。他们已经向我发送了他们实际的.cer文件,目前我直接将其拉出来并获取公钥。然后将其传递给check签名函数。任何帮助或指点将不胜感激,并让我知道如果任何澄清是必要的。我没有得到任何错误,只是每次都在检查签名方法上出错,不管发生什么。我已经尝试将编码从utf-8更改为ASCII。毫无用处,似乎什么都不管用,我快发疯了!哈哈 这就是逻辑:C# SAML RSA FIM(EMC)无法验证签名,c#,.net,single-sign-on,saml-2.0,C#,.net,Single Sign On,Saml 2.0,我作为服务提供商实施SSO,ID提供商是RSA FIM,又称EMC。我成功地向他们发送了一个AuthN请求并收到了一个saml响应,但我似乎只是验证了签名。他们已经向我发送了他们实际的.cer文件,目前我直接将其拉出来并获取公钥。然后将其传递给check签名函数。任何帮助或指点将不胜感激,并让我知道如果任何澄清是必要的。我没有得到任何错误,只是每次都在检查签名方法上出错,不管发生什么。我已经尝试将编码从utf-8更改为ASCII。毫无用处,似乎什么都不管用,我快发疯了!哈哈 这就是逻辑: /*G
/*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;
}
/*在前面的函数中获取XML并构建saml文档*/
字节[]base64EncodedBytes=Convert.FromBase64String(samlResponse);
samlXml=System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
_SamlDocument=newxmldocument();
_SamlDocument.PreserveWhitespace=true;
_LoadXml(samlXml);
/*验证功能*/
公共布尔验证()
{
//检查参数。
如果(_SamlDocument==null)
抛出新ArgumentException(“无效的XML文档”);
//创建一个新的SignedXml对象并传递它
//XML文档类。
SamlSignedXml signedXml=新的SamlSignedXml(_SamlDocument,“ID”);
XmlNamespaceManager=newxmlnamespacemanager(_SamlDocument.NameTable);
manager.AddNamespace(“ds”,SamlSignedXml.XmlDsigNamespaceUrl);
//找到“签名”节点并创建一个新的
//XmlNodeList对象。
XmlNodeList nodeList=\u SamlDocument.SelectNodes(“//ds:Signature”,manager);
//如果未找到签名,则引发异常。
如果(nodeList.Count=2)
{
抛出新的加密异常(“验证失败:为文档找到了多个签名。”);
}
//加载第一个节点。
signedXml.LoadXml((xmlement)节点列表[0]);
var bVerified=假;
/*直接从作为文件位置的品牌证书字符串中拉入.cer文件*/
X509Certificate2 brandCert=新X509Certificate2(brandCertificateString);
bVerified=signedXml.CheckSignature(brandCert.PublicKey.Key);
返回验证;
}
/发送的saml响应示例/
\u删除的信息_
Bi9EXd/yvWKHV7Hvc8tB3ddmDW8=
eCwiyItypMUOW9dUs8nEx5ufKRZfwCcDKTvkEYa4UQA048N9Sno4/tPJICenhV/5SCjnMSR4wx5q
FKcS5FiMK0q1JFl3qeDzUwl1zH1kqJQjS1fUatC7SKvCRRAI25nNapGT/4DZiaTmEt3tzf/o36b0
HHYULKFI3RLAETZJ91VE7UH5DOI6GPAAG9P8RTBDxVNHSGNUYIAJOG8MUUXUD3WAUDNAHMVUBSQ
RJSR0GW4X92K60LBMCU+qHNtpZyT96LyKVW5MF9HklQOkEW0ip8AJD3u6n3RTAtQnmoIJIOzSzH
15PNMOJVWZD7UQNWJAZIJWR7NYIDBSPggytva==
_removedinformation\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu_
谢谢,
马克多亏基思的《从这里来》我才找到了答案()。使用名称管理器深入到签名节点非常有效,为我提供了一个干净的签名验证。我不得不稍微修改,以便从响应节点而不是断言节点提取签名,但它工作得很好。非常感谢你,基思
// 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);
// 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);