0

i have the following piece of code. It has been working in my Staging and pre-production environments as well as in production.

How it has suddenly stopped working ONLY in the Production environment. It still works in pre-production and production.

It is throwing the "Hash value does not match" error meaning the storedHash != calcHash.

Any ideas why this might be happening in only of the 3 environments?

static public string StrDec(string value, string key)
{
    String dataValue = "";
    String calcHash = "";
    String storedHash = "";

    MACTripleDES mac3des = new MACTripleDES();
    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
    mac3des.Key = md5.ComputeHash(Encoding.UTF8.GetBytes(key));
    try
    {
       string strRemoveSpace = value.Replace(" ", "+");
       dataValue = Encoding.UTF8.GetString(System.Convert.FromBase64String(strRemoveSpace.Split(System.Convert.ToChar("-"))[0]));
       storedHash = Encoding.UTF8.GetString(System.Convert.FromBase64String(strRemoveSpace.Split(System.Convert.ToChar("-"))[1]));
       calcHash = Encoding.UTF8.GetString(mac3des.ComputeHash(Encoding.UTF8.GetBytes(dataValue)));

        if (storedHash != calcHash)
        {
            //Throw exception because data was corrupted here
            throw new ArgumentException("Hash value does not match");
        }
    }
    catch (System.Exception ex)
    {
        //Catch System.Exception  here
    }
    return dataValue;
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
StackTrace
  • 9,190
  • 36
  • 114
  • 202
  • Just a minor thing - your code would be easier to read if you weren't fully-qualifying all the type names. Also, could you give us sample input and output data? – Jon Skeet Jul 10 '14 at 06:13
  • 1
    Default Base64 alphabet uses `'+'` character (and file-safe Base64 variants usually use `'-'` character). In your code you are replacing spaces with `'+'` which could lead to radically different Base64 value or even invalid Base64 representation. – Oleg Estekhin Jul 10 '14 at 06:21
  • @JonSkeet, sample data for strRemoveSpace varibale is "NjQ5Njk5NTc=-Ph6FUlzZISI=" WHILE sample data for dataValue variable is "64969957" – StackTrace Jul 10 '14 at 06:39

2 Answers2

1

This is the problem - or at least a problem:

Encoding.UTF8.GetString(mac3des.ComputeHash(Encoding.UTF8.GetBytes(dataValue)));

... and quite possibly the same for the previous lines.

You're calling Encoding.UTF8.GetString with arbitrary binary data which isn't a UTF-8-encoded string. You mustn't do that - it's like trying to load an arbitrary blob of data as an image file.

If you want to convert some arbitrary binary data to a string, use Convert.ToBase64String or convert it to hex.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • thanks for pointing that out. But in my quest to further understand this problem, do you of some reason why its only happening now and only in one environments. What other system/environmental factors might it be dependent upon since the same data throws an exception in environment but to the other? – StackTrace Jul 10 '14 at 07:14
  • 1
    @SQL.NETWarrior: Are you certain it's the exact same data? It's possible that one runtime has a slightly different way of handling garbage data than the other - which is unfortunate, but is fixed by not providing garbage data :) – Jon Skeet Jul 10 '14 at 07:15
  • Is the following your suggest recommended way? calcHash = Convert.ToBase64String(mac3des.ComputeHash(Encoding.UTF8.GetBytes(dataValue))); – StackTrace Jul 10 '14 at 08:04
  • @SQL.NETWarrior: Yes, that's definitely better. Given that you were already using base64 in your stored hash by the looks of it, you can probably then avoid the call to `Convert.FromBase64String`. (We don't really know what your `dataValue` is, by the way... I'd be suspicious of *all* those `Encoding.UTF8.GetString(...)` calls.) – Jon Skeet Jul 10 '14 at 08:06
-2
    // Verify the signature of an XML file and return the result.
    public static Boolean VerifySignRequest(String requestXML, string privateKeyIdentifier)
    {
        bool isValid = false;
        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            X509Store store = new X509Store(StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);

            X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySubjectKeyIdentifier, privateKeyIdentifier, false);
            X509Certificate2 cert = certs[0];

            // Create a new XML document.
            XmlDocument xmlDocument = new XmlDocument();

            // Format using white spaces.
            xmlDocument.PreserveWhitespace = true;

            // Load the passed XML file into the document. 
            xmlDocument.LoadXml(requestXML);

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

            // Find the "Signature" node and create a new
            // XmlNodeList object.
            XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature", "http://www.w3.org/2000/09/xmldsig#");

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

            // Check the signature and return the result.
            isValid = signedXml.CheckSignature(cert,true);
        });
        return isValid;
    }

    /// <summary>
    /// SignedXmlWithId
    /// </summary>
    public class SignedXmlWithId : SignedXml
    {
        public SignedXmlWithId(XmlDocument xml)
            : base(xml)
        {
        }

        public SignedXmlWithId(XmlElement xmlElement)
            : base(xmlElement)
        {
        }

        public override XmlElement GetIdElement(XmlDocument doc, string id)
        {
            // check to see if it's a standard ID reference
            XmlElement idElem = base.GetIdElement(doc, id);

            if (idElem == null)
            {
                XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);
                nsManager.AddNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

                idElem = doc.SelectSingleNode("//*[@wsu:Id=\"" + id + "\"]", nsManager) as XmlElement;
            }

            return idElem;
        }
    }
solohero
  • 1
  • 1