2009-10-05 14 views
7

Qual è il modo migliore per eseguire l'hashing di un documento XML in C#? Mi piacerebbe hash un documento XML in modo che io possa dire se è stato modificato manualmente da quando è stato generato. Non sto usando questo per sicurezza - va bene se qualcuno cambia l'XML, e cambia l'hash in modo che corrisponda.Generazione di un hash di documenti XML in C#

Per esempio, mi piacerebbe hash i nodi figlio della radice e memorizzare l'hash come un attributo della radice:

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

In che modo gli spazi bianchi entrano in gioco nell'asportazione desiderata? –

+0

Sono fuori discussione: da un lato, mi preoccupo solo dei dati, non della formattazione. D'altra parte, l'identificazione di * eventuali * cambiamenti potrebbe essere utile per verificare se qualcuno stesse giocando con il file. –

risposta

7

.NET ha classes che implementa lo XML digital signature spec. La firma può essere aggiunta all'interno del documento XML originale (ad esempio una "firma con involucro") o memorizzata/trasferita separatamente.

Potrebbe essere un po 'eccessivo dato che non è necessaria la sicurezza, ma ha il vantaggio di essere già implementato e di essere uno standard che non dipende da una lingua o piattaforma.

+0

Mi piace questa soluzione, perché come hai sottolineato, è già implementata ed è uno standard. –

4

È possibile utilizzare lo spazio nome di crittografia:

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

Hai solo bisogno di usare una chiave per creare l'hashing crittografo e quindi creare un hash con la reqpresentazione della stringa del tuo xml.

+1

vedere anche System.Security.Cryptography.MD5, System.Security.Cryptography.SHA1, System.Security.Cryptography.SHA256, ecc. E confrontare le recensioni qui: http://en.wikipedia.org/wiki/Cryptographic_hash_function –

+2

Codifica. L'impostazione predefinita è la codifica per la tabella codici ANSI corrente del sistema operativo. Il tuo codice darà quindi risultati diversi a seconda delle impostazioni nella scheda Opzioni internazionali e della lingua - Avanzate. –

+0

wcoenen ha un punto molto giusto. Utilizza Encoding.ASCII o Encoding. . –

2

Aggiungere un riferimento .NET a System.Security e utilizzare XmlDsigC14NTransform. Ecco un esempio ...

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