Quantcast
Channel: .NET Framework Class Libraries forum
Viewing all articles
Browse latest Browse all 8156

SignedXml.Checksignature returns false

$
0
0

Trying this with .NetFramework 4.0.

I am working on implementatio of SSO using SAML for security. My code need to work as a Identity Service Provider where I need to validate a SAML Assertion generated from customer's Federation Server and sent to my web-site. As of now everything was good till I received a SAML Assertion with SHA1 algoritm but when it starts sending SHA256, the nighemare started. :)

Well, I have read a lot around this and implemented provided suggestions but could not get through it yet. I have two ways to validate no one is working.

In below code, as .Net Framework 4.0 does not support SHA256, I have create extension class (public class RSAPKCS1SHA256SignatureDescription : SignatureDescription) as mentioned here we well as here2, but did not help.

Any help would be saviour.

1. With only SAML Assertion hits my site (code is below). Always getting Fals as result from Checksignature.

RSAPKCS1SHA256SignatureDescription.Register();

XmlNamespaceManager nsm = new XmlNamespaceManager(new NameTable());
                nsm.AddNamespace("dsig", SignedXml.XmlDsigNamespaceUrl);
                XmlElement sigElt = (XmlElement)m_xmlDoc.SelectSingleNode("//dsig:Signature", nsm);

                // Load the signature for verification
                SignedXml sig = new SignedXml(m_xmlDoc);
                sig.LoadXml(sigElt);
                if (!sig.CheckSignature())
                    return "Invalid Signature";

2. With the certificate (.cer) file provided by client and situated locally on Server.

///// WAY - 1
private string VerifyCert1()
        {
//m_xmlDoc - is a received SAMLAssertion converted to text
            if (m_xmlDoc == null)
                return "Could not load SAMLResponse in XMLDocument object";

            if (m_useExternalCertificate && m_cert == null)
                return "Could not load certificate in X509Certificate object from file";

			// Call to register SHA256
			RSAPKCS1SHA256SignatureDescription.Register();

            SamlSignedXml msSignedXML = new SamlSignedXml(m_xmlDoc);
            string xmlDsigNS = "http://www.w3.org/2000/09/xmldsig#";

            XmlNodeList nodeList = null;
            XmlNodeList keyInfoNodes = null;
            RSACryptoServiceProvider rsaKey = null;

            try
            {
                nodeList = m_xmlDoc.GetElementsByTagName("Signature", xmlDsigNS);
                rsaKey = GetPubKeyFromCert();

                keyInfoNodes = m_xmlDoc.GetElementsByTagName("KeyInfo");
                if (keyInfoNodes.Count > 0)
                {
                    nodeList[0].RemoveChild(keyInfoNodes[0]);
                }
                msSignedXML.LoadXml((XmlElement)nodeList[0]);

                if (!msSignedXML.CheckSignature(rsaKey))
                    return "Invalid Signature";
            }
            catch (Exception e)
            {
                return e.Message;
            }
            return "success";
        }

////////////////////////////////
///// WAY - 2
private string VerifyCert2()
        {
            if (m_xmlDoc == null)
                return "Could not load SAMLResponse in XMLDocument object";

            if (m_useExternalCertificate && m_cert == null)
                return "Could not load certificate in X509Certificate object from file";

			// Call to register SHA256
            RSAPKCS1SHA256SignatureDescription.Register();

            string xmlDsigNS = "http://www.w3.org/2000/09/xmldsig#";

            XmlNodeList nodeList = null;
            XmlNodeList keyInfoNodes = null;
            RSACryptoServiceProvider rsaKey = null;

            try
            {

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

                rsaKey = GetRSAPublicKeyFromCertificate();

                System.Security.Cryptography.Xml.Reference refDocNode =
                    new System.Security.Cryptography.Xml.Reference(nodeList[0].Attributes["URI"].Value);

                SignedXml refDocument = new SignedXml(m_xmlDoc);

                refDocument.AddReference(refDocNode);
                refDocument.SigningKey = new RSACryptoServiceProvider(2048);
                refDocument.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigC14NTransformUrl;
                refDocument.ComputeSignature();

                SignedXml mainDoc = new SignedXml(m_xmlDoc);

                mainDoc.LoadXml(refDocument.GetXml());

                if (!mainDoc.CheckSignature(rsaKey))
                    return "Invalid Signature";

            }
            catch (Exception e)
            {
                return e.Message;
            }
            return "success";
        }

		//Utility function
private RSACryptoServiceProvider GetRSAPublicKeyFromCertificate()
        {
            RSACryptoServiceProvider rsaKey = null;
            RSAParameters rsaParams = new RSAParameters();
            CspParameters cspParam = new CspParameters();

                  //------------------------
            cspParam.Flags = CspProviderFlags.NoFlags;
            cspParam.KeyContainerName = Guid.NewGuid().ToString().ToUpperInvariant();
            cspParam.ProviderType = ((Environment.OSVersion.Version.Major > 5) || ((Environment.OSVersion.Version.Major == 5) && (Environment.OSVersion.Version.Minor >= 1))) ? 0x18 : 1;

            byte[] publicKeyBytes = m_cert.GetPublicKey();
            byte[] exponents = null;
            byte[] modulus = null;

            //MOD
			//m_cer is created from .cer file which is available - its created as
			//			 m_cert = new X509Certificate2(m_certPath, "", X509KeyStorageFlags.Exportable);
            RSACryptoServiceProvider key = m_cert.PublicKey.Key as RSACryptoServiceProvider;

            if (key != null)
            {
                RSAParameters parameters = key.ExportParameters(false);
                exponents = parameters.Exponent;
                modulus = parameters.Modulus;
            }
            //------------------------

            rsaParams.Modulus = modulus;
            rsaParams.Exponent = exponents;

            rsaKey = new RSACryptoServiceProvider(cspParam);
            rsaKey.ImportParameters(rsaParams);
            return rsaKey;
        }

Regards

Sandeep


"An investment in knowledge pays the best interest." - Ben Franklin



Viewing all articles
Browse latest Browse all 8156

Latest Images

Trending Articles



Latest Images