2009-10-05 3 views
7

Каков наилучший способ хэширования XML-документа на C#? Я хотел бы хэш XML-документ, чтобы я мог определить, было ли оно вручную изменено с момента его создания. Я не использую это для обеспечения безопасности - все в порядке, если кто-то меняет XML и меняет хэш на соответствие.Создание хеша XML-документа в C#

Например, я бы хэширование дочерних узлов корня и хранить хэш в качестве атрибута корня:

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

Как пробелы вступают в игру в желаемом хешировании? –

+0

Я нахожусь на заборе об этом - с одной стороны, я действительно забочусь только о данных, а не о форматировании. С другой стороны, определение * любых * изменений может быть полезно для проверки того, играл ли кто-нибудь с файлом. –

ответ

7

. NET имеет classes, которые реализуют XML digital signature spec. Подпись может быть добавлена ​​в исходный XML-документ (т. Е. «Окутанная подпись») или храниться/передаваться отдельно.

Это может быть немного перехитрить, поскольку вам не нужна безопасность, но она имеет то преимущество, что уже реализована, и является стандартом, который не зависит от языка или платформы.

+0

Мне нравится это решение, потому что, как вы указали, оно уже реализовано и является стандартом. –

4

Вы можете использовать имя криптографии пространство:

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

Вам просто нужно использовать ключ для создания хеширующего криптографа, а затем создать хеш с строковым представлением вашего xml.

+1

см. Также System.Security.Cryptography.MD5, System.Security.Cryptography.SHA1, System.Security.Cryptography.SHA256 и т. Д. И сравнительное сравнение здесь: http://en.wikipedia.org/wiki/Cryptographic_hash_function –

+2

Кодировка. По умолчанию используется кодировка текущей кодовой страницы ANSI операционной системы. Таким образом, ваш код будет давать разные результаты в зависимости от настроек на вкладке «Язык и региональные стандарты» - «Дополнительно». –

+0

wcoenen имеет очень справедливую точку. Используйте Encoding.ASCII или Encoding. <Некоторая согласованная кодировка>. –

2

Добавьте ссылку .NET в System.Security и используйте XmlDsigC14NTransform. Вот пример ...

/* 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; 
} 
Смежные вопросы