2009-10-05 8 views
7

Quelle est la meilleure façon de hacher un document XML en C#? Je voudrais hacher un document XML afin que je sache s'il a été modifié manuellement à partir du moment où il a été généré. Je n'utilise pas cela pour la sécurité - c'est OK si quelqu'un change le XML, et change le hachage à faire correspondre.Générer un hachage de document XML en C#

Par exemple, je Hash les nœuds enfants de la racine et de stocker le hachage comme un attribut de la racine:

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

Comment les espaces entrent-ils en jeu dans votre hachage? –

+0

Je suis sur la clôture à ce sujet - d'une part, je me soucie seulement des données, pas du formatage. D'un autre côté, identifier * tout * changement pourrait être utile pour vérifier si quelqu'un jouait avec le fichier. –

Répondre

7

.NET a classes qui implémentent le XML digital signature spec. La signature peut être ajoutée à l'intérieur du document XML original (c'est-à-dire une "signature enveloppée"), ou stockée/transférée séparément.

C'est peut-être un peu exagéré car vous n'avez pas besoin de la sécurité, mais il a l'avantage d'être déjà implémenté, et d'être un standard qui ne dépend pas d'un langage ou d'une plate-forme. Ajoutez une référence .NET à System.Security et utilisez XmlDsigC14NTransform.

+0

J'aime cette solution, car comme vous l'avez souligné, elle est déjà implémentée et est une norme. –

4

Vous pouvez utiliser l'espace de nom de cryptographie:

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

Vous avez juste besoin d'utiliser une clé pour créer le cryptographe de hachage et ensuite créer un hachage avec la chaîne reqpresentation de votre xml.

+1

voir aussi System.Security.Cryptography.MD5, System.Security.Cryptography.SHA1, System.Security.Cryptography.SHA256, etc. et de comparer la comparaison ici: http://en.wikipedia.org/wiki/Cryptographic_hash_function –

+2

Encodage. La valeur par défaut est l'encodage de la page de code ANSI actuelle du système d'exploitation. Votre code donnera donc des résultats différents en fonction des paramètres de l'onglet Options régionales et linguistiques - Avancé. –

+0

wcoenen a un très bon point. Utilisez Encoding.ASCII ou Encoding. . –

2

Voici un exemple ...

/* 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; 
} 
Questions connexes