Generating an XML document hash in C#

11,052

Solution 1

.NET has classes that implement the XML digital signature spec. The signature can be added inside the original XML document (i.e. an "enveloped signature"), or stored/transferred separately.

It may be a bit overkill since you don't need the security, but it has the advantage of being already implemented, and being a standard which does not depend on a language or platform.

Solution 2

You can use the cryptography name space:

System.Security.Cryptography.MACTripleDES hash = new System.Security.Cryptography.MACTripleDES(Encoding.Default.GetBytes("mykey"));
string hashString = Convert.ToBase64String(hash.ComputeHash(Encoding.Default.GetBytes(myXMLString)));

You just need to use a key to create the hashing cryptographer and then create a hash with the string reqpresentation of your xml.

Solution 3

Add a .NET reference to System.Security, and use XmlDsigC14NTransform. Here's an example...

/* http://www.w3.org/TR/xml-c14n

    Of course is cannot detect these are the same...

       <color>black</color>    vs.   <color>rgb(0,0,0)</color>

    ...because that's dependent on app logic's interpretation of XML data.

    But otherwise it gets the following right...
    •Normalization of whitespace in start and end tags
    •Lexicographic ordering of namespace and attribute
    •Empty element conversion to start-end tag pair 
    •Retain all whitespace between tags

    And more.
 */
public static string XmlHash(XmlDocument myDoc)
{
    var t = new System.Security.Cryptography.Xml.XmlDsigC14NTransform();
    t.LoadInput(myDoc);
    var s = (Stream)t.GetOutput(typeof(Stream));
    var sha1 = SHA1.Create();

    var hash = sha1.ComputeHash(s);
    var base64String = Convert.ToBase64String(hash);
    s.Close();
    return base64String;
}
Share:
11,052
sourcenouveau
Author by

sourcenouveau

computers rule, humans drool

Updated on June 04, 2022

Comments

  • sourcenouveau
    sourcenouveau about 2 years

    What's the best way to go about hashing an XML document in C#? I'd like to hash an XML document so that I can tell if it was manually changed from when it was generated. I'm not using this for security--it's OK if someone changes the XML, and changes the hash to match.

    For example, I'd hash the child nodes of the root and store the hash as an attribute of the root:

    <RootNode Hash="abc123">
        <!-- Content to hash here -->
    </RootNode>