| 

.NET C# Java Javascript Exception

0
Hallo,

ich bin momentan dabei mich in TDD einzuarbeiten. Ich benoetige in einem Programm eine Methode um sicherzustellen, dass die Daten die ich einlese nicht manipuliert wurden.

Um das zu tun habe ich mir folgendes vorgehen ausgedacht. Ich lade meine Datenklasse mit den gelesenen Daten und einem Hashwert der Daten. Beim laden wird der Hash erneut berechnet und mit dem uebermittelten verglichen.

Soweit ist alles klar... wenn ich nicht dazu auch gleich meinen Unit test schreiben will. Ich bin mir dabei nicht so sicher ob das vorgehen so sinnvoll ist. Ich werde das mal versuchen am Beispiel zu erklaeren. Dazu nehme ich die Klasse Daten die ueberprueft werden soll. Aufbau wie folgt.

public class Daten {
private const string SALT = "xyz";
public string Name { get; set; }
public string Wert { get; set; }
public int Zahl { get; set; }

// Wird beim speichern einmalig berechnet und gesetzt
public string Hash { get; set; }

public override string ToString() {
return String.Format("{0}//{1}//{2}", Name, Wert, Zahl);
}
}


Die berechnung des Hashes soll zentral erfolgen, da ich diese Pruefungen fuer mehrere Klassen benoetige.

public static class Hash {
public static string Calculate(string salt, string value) {
byte[] data = new UnicodeEncoding().GetBytes(salt + value);
byte[] result = (HashAlgorithm)CryptoConfig.CreateFromName("MD5").ComputeHash(data);
return BitConverter.ToString(result);
}
}


Was ist dazu nun ein Sinnvoller test? Ich habe zuerst ueberlegt etwas wie dies zu tun.

private const string SALT = "123xyz";

[Test]
public void CalculateTheHash() {
string hash = Hash.Calculate(SALT, "Dieser Satz ist ein Testsatz");
Assert.AreEqual(hash, "xxxxxxx");
}


Das Problem dabei ist nun wie errechne ich mir den gewuenschten vergleichswert, bevor ich meinen Code dazu geschrieben habe, da ich sonst meinen Test nach dem Code schreiben muesste um den Hash zu berechnen um ihn in den Code einzugeben.

Die andere Frage ist, ob dieses vorgehen ueberhaupt sinnvoll ist bzw. ob es eine guenstigere Moeglichkeit gibt sicherzustellen, dass nicht manipuliert wurde.
News:
27.04.2010
Booser 13 4
2 Antworten
0
1. du nimmst eines oder mehrere belibige Programme die die gleichen Hashs generieren können. Diese nimmst du dann als Vergleichswert.

2. bin ich mir nicht mal sicher ob man einen Test der letztendlich nur eine Systemfunktion kapselt einen Test schreiben muss. Falls ja (siehe 1.)
27.04.2010
Floyd 14,6k 3 9
Wie mich schonmal jemand darauf hingewiesen hat ist es ja eher so, dass ich meinen Test schreibe und dann Code schreibe der das zu testende implementiert. Was so dem TDD gedanken entspricht. Dem stimme ich auch aus meiner Sicht zu. Der oben genannte Codeteil ausser dem Test Code ist einem alten Projekt entnommen an dem ich mal gearbeitet habe und das ich als Beispiel herangezogen habe. Ich werde dann wohl mal den Testsatz Hash generieren lassen und daraus meinen Testcode schreiben xD
Booser 02.05.2010
TDD ist eine Hilfe/ein Konzept und kein Dogma.
Zwar solltest du für alle Funktionen eine Test-Funktion vorher schreiben jedoch ist das in manchen Fällen a sinnlos oder b zu aufwändig.
Wenn du für eine solche Funktion einen Test schreiben willst musst du zwangsweise zuerst mehrere alternative MD5-Hashimplementierungen dazu bringen einen Hash mit deinen Spezifikationen zu erzeugen. Diese müßten dann, bei gleichem Input, identisch sein. Das Ergebnis vergleichst du dann mit deinem Ergebnis bzw. dem Ergebnis deiner Funktion. Einen anderen Weg gibt es nicht.
Floyd 02.05.2010
Wobei ich dazu sagen muss, das ich das ganze Konzept der TDD zwar an machen Stellen für sinvoll erachte, es einen jedoch oft sehr stark einschränkt. Bei mir ist es so das ich unsere Software on the fly entwickeln muss. Die Anforderungen an den Code ändern sich machmal mehrmals untertägich so das ich TDD nur bei Hilfsfunktionen benutzen könnte.
Fazit: TDD ist an machen Stellen sinvoll, an anderen wiederrum unbrauchbar. Hier sollte man immer abwägen.
Gerade wenn man kein festen Softwaredesign vor sich hat, ist es möglich, erst die Funktion und dann dazu einen Test zu schreiben.
Floyd 02.05.2010
0
Soweit ich es sehe gibt es in deiner Klasse mehrere Variablen. Neben dem Text kann sich auch der SALT, das Encoding, der Hash Algorithmus und letztendlich die Konvertierung in einen String geändert werden. Insofern macht ein Test durchaus einen Sinn. Und das, auch wenn der erwartete Wert mit der eigenen Funktion initial belegt wird.

Du willst nach Optimierungen sicherstellen, das die Funktion immer noch funktioniert (wie zuvor), bei Änderung des Salt Parameter sollen andere Hashwerte generiert werden, bei Änderung des Textes sollen andere Hashwerte generiert werden, mögliche Hash Kollisionen sollen gefunden werden, was macht deine Funktion wenn String.Empty oder null übergeben wird. Das sollten einige Anregungen sein.

Nebenbei ist die Salt Konstante in der Datenklasse nicht sinnvoll, meine ich. Instanzen der Klasse würden bei gleichen Werten den gleichen Hash erzeugen, das tun sie aber auch ohne Salt.

Die Datenklassen sollen gegen Manipulation geschützt werden? Da hilft der Hash nur zu erkennen das manipuliert wurde, vielleicht solltest du die Änderungen nur auf vorgesehene Weise ermöglichen, ansonsten gegen Änderung schützen.
05.05.2010
me 1,1k 2 9
Ich werde wohl den obigen Test verwenden da ich eben nicht NUR EINE Funktion des Frameworks benutze.
Die Anregungen zur Optimierung werde ich mal so annehmen, Danke.
Ich verwende die Methode des Hashens nicht um zu verhindern, dass die Daten IM Programm veraenderungssicher sind. Ich will sicherstellen, dass daten die zB aus XML eingelesen werden nicht manipuliert wurden. Oder auch die DB Daten korrekt sind.
Ich werde aber wahrscheinlich doch anstatt fuer jede Klasse einen eigenen Salt zu verwenden doch nur einen Wert für alle Klassen nehmen und diesen in der Hash Klasse lagern
Booser 14.05.2010

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH