Request SAML请求签名验证c#

Request SAML请求签名验证c#,request,x509certificate,saml,signature,verification,Request,X509certificate,Saml,Signature,Verification,我正在创建一个SAML身份提供者,我们的服务提供者正在使用第三方工具组件空间来完成他们的最终工作。我开发的身份提供程序从用户获取登录凭据,并在我们的active directory联合服务器上验证该用户。如果用户有效,那么我将创建一个SAMLResponse,使用X509Certificate对其进行签名,并将其发布到我从SAMLRequest收到的AssertionConsumerServiceURL。现在,我需要验证SAMLRequest是否来自有效的服务提供商,并且在这两者之间没有被修改

我正在创建一个SAML身份提供者,我们的服务提供者正在使用第三方工具组件空间来完成他们的最终工作。我开发的身份提供程序从用户获取登录凭据,并在我们的active directory联合服务器上验证该用户。如果用户有效,那么我将创建一个SAMLResponse,使用X509Certificate对其进行签名,并将其发布到我从SAMLRequest收到的AssertionConsumerServiceURL。现在,我需要验证SAMLRequest是否来自有效的服务提供商,并且在这两者之间没有被修改

最初,服务提供者使用HTTP重定向绑定并在查询字符串中发送SAMLRequest、SigAlg和签名,我尝试在下面的代码中验证签名,但它总是返回false

public bool VerifyHashDynamic(string Signature, string request)
        {
            bool isVerified = false;

            X509Certificate2 x509 = new X509Certificate2(Server.MapPath(".") + @"\X509Certificate\SP.cer", "password");
            byte[] signature = Base64DecodeArray(Signature);
            byte[] signedData = Base64DecodeArray(request);
            RSACryptoServiceProvider rsaCSP = (RSACryptoServiceProvider)x509.PublicKey.Key;
            SHA256Managed hash = new SHA256Managed();
            byte[] hashedData;
            bool dataOK = rsaCSP.VerifyData(signedData, CryptoConfig.MapNameToOID("SHA256"), signature);

            hashedData = hash.ComputeHash(signedData);
            isVerified = rsaCSP.VerifyHash(hashedData, CryptoConfig.MapNameToOID("SHA256"), signature);

            return isVerified;
        }
上面允许签名验证的代码中是否有错误

为了让它以另一种方式工作,我要求我们的服务提供商发送带有嵌入签名(HTTP-POST绑定)的AuthNRequest。对于已发布AuthnRequest的签名验证,我尝试了XMLDocument验证,代码如下:

 public Boolean VerifyXml()
    {
        string mystr = string.Empty;

        mystr = "9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkIiBBbGxvd0NyZWF0ZT0idHJ1ZSIgLz48L3NhbWxwOkF1dGhuUmVxdWVzdD4=";
        mystr = GetXmlFromSAML(mystr, false);
        mystr = mystr.TrimEnd().TrimStart();
        X509Certificate2 myCert = new X509Certificate2(Server.MapPath(".") + @"\X509Certificate\SP.cer");
        XmlDocument Doc = new XmlDocument();
        Doc.PreserveWhitespace = false;
        Doc.XmlResolver = null;
        Doc.LoadXml(mystr);

        // Check arguments.
        if (Doc == null)
            throw new ArgumentException("Doc");


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

        // Find the "Signature" node and create a new
        // XmlNodeList object.
        XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");

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

        // Check the signature and return the result.
        return signedXml.CheckSignature(myCert, false);
    }
public Boolean VerifyXml()
{
string mystr=string.Empty;
mystr=“9invybjpvyxnpczpuyy1lczp0yzptqu1mojeumtpuyw1lawqtzm9ybwf0onvuc3bly2lmawvkibbgxvd0nyzwf0zt0idhj1zsiglz48l3nhbwxwokf1dghuumvxdwzdd4=”;
mystr=GetXmlFromSAML(mystr,false);
mystr=mystr.TrimEnd().TrimStart();
X509Certificate2 myCert=新的X509Certificate2(Server.MapPath(“.”+@“\X509Certificate\SP.cer”);
XmlDocument Doc=新的XmlDocument();
Doc.PreserveWhitespace=false;
Doc.xmlsolver=null;
Doc.LoadXml(mystr);
//检查参数。
如果(Doc==null)
抛出新的ArgumentException(“Doc”);
//创建一个新的SignedXml对象并传递它
//XML文档类。
SignedXml SignedXml=新的SignedXml(Doc);
//找到“签名”节点并创建一个新的
//XmlNodeList对象。
XmlNodeList nodeList=Doc.GetElementsByTagName(“签名”);
//如果未找到签名,则引发异常。
如果(nodeList.Count=2)
{
抛出新的加密异常(“验证失败:为文档找到了多个签名。”);
}
//加载第一个节点。
signedXml.LoadXml((xmlement)节点列表[0]);
//检查签名并返回结果。
返回signedXml.CheckSignature(myCert,false);
}
使用上述验证代码,我得到异常“无法为提供的签名算法创建SignatureDescription”。我不知道如何才能让这个签名验证工作

是否确实可以使用X509Certificate手动验证SAMLRequest签名?允许登录检查而不验证AuthnRequest的签名可以吗


过去一个月,我一直在谷歌上搜索所有这些内容,但运气不好。非常感谢您的帮助。

在XmlDocument版本中,我想您需要
Doc.PreserveWhitespace=true但这并没有导致错误。参数
字符串请求
是什么样子的?SAML对于包含SigAlg和零件顺序非常精确。将其推入Base64DecodeArray()的方式使人对内容产生怀疑。在XmlDocument版本中,它应该看起来像
SAMLRequest=value&RelayState=value&SigAlg=value
,我想您需要
Doc.PreserveWhitespace=true但这并没有导致错误。参数
字符串请求
是什么样子的?SAML对于包含SigAlg和零件顺序非常精确。将其推入Base64DecodeArray()的方式使人对内容产生怀疑。它应该看起来像
SAMLRequest=value&RelayState=value&SigAlg=value