Guten Tag,
ich lese schon sehr lange hier im Forum und habe oft Antworten auf meine Fragen gefunden. Aus diesem Grund habe ich mich heute angemeldet und muss direkt mal eine erste Frage stellen.
Hintergrund:
Ich möchte
XML-Dateien gegen Manipulation schützen. Diese
XML-Datei enthält Messdaten, welche nicht verändert werden sollen. Die
XML-Datei soll aber trotzdem lesbar bleiben. Es genügt beim öffnen der Datei eine Überprüfung, ob die Datei verändert wurde.
In einer ersten Version habe ich lediglich die Werte aller Attribute eingelesen, als Strings aneinander gehängt und daraus dann einen Hashwert bestimmt, welchen ich ebenso in der
XML speicher:
Delphi-Quellcode:
procedure TForm1.SchreibeXML;
var
xmlDoc : IXMLDocument;
iNode: IXMLNode;
s: string;
Hashwert: string;
begin
ErstelleXML;
xmlDoc := newXMLDocument;
XMLDoc.LoadFromFile(PATH + Dateiname);
xmlDoc.Active := true;
//Neue Knoten anlegen
XMLDoc.DocumentElement.AddChild('messdaten');
XMLDoc.DocumentElement.AddChild('hashdaten');
//Attribute zuweisen - Messwerte
iNode := XMLDoc.DocumentElement.ChildNodes['messdaten'].AddChild('messwerte');
iNode.Attributes['text'] := TextEdt.Text;
iNode.Attributes['messwert1'] := Messwert1Edt.Text;
iNode.Attributes['messwert2'] := Messwert2Edt.Text;
iNode.Text := '';
s := TextEdt.Text + Messwert1Edt.Text + Messwert2Edt.Text;
Hashwert := getMd5HashString(s);
//Attribute zuweisen - Hashwert
iNode := XMLDoc.DocumentElement.ChildNodes['hashdaten'].AddChild('hash');
iNode.Attributes['wert'] := Hashwert;
iNode.Text := '';
//Speichern
xmlDoc.SaveToFile(PATH + Dateiname);
Die
XML-Datei sieht dann z.B. so aus:
Code:
<?
xml version="1.0"?>
<Root>
<messdaten>
<messwerte text="Titel" messwert1="2.5" messwert2="7.6"/>
</messdaten>
<hashdaten>
<hash wert="4b0fbe5ec8db72fe0ffaf8e1cbc9f50f"/>
</hashdaten>
</Root>
Beim Einlesen haben ich diesen Hashwert dann analog berechnet und ihn mit dem Wert in der
XML verglichen. Das funktioniert schonmal sehr gut.
Nun möchte ich aber generelle Manipulationen in der
XML-Datei erkennen können. Ich möchte somit alles bis auf den Knoten "hashdaten" hashen.
Ich scheitere jedoch schon bei der Berechnung des Hashwertes. Mein Ansatz:
Delphi-Quellcode:
procedure TForm1.SchreibeXML;
var
xmlDoc : IXMLDocument;
iNode: IXMLNode;
s: string;
Hashwert: string;
Stream: TStream;
begin
ErstelleXML;
xmlDoc := newXMLDocument;
xmlDoc.LoadFromFile(PATH + Dateiname);
xmlDoc.Active := true;
//Neuen Knoten anlegen - Messdaten
xmlDoc.DocumentElement.AddChild('messdaten');
//Attribute zuweisen - Messwerte
iNode := XMLDoc.DocumentElement.ChildNodes['messdaten'].AddChild('messwerte');
iNode.Attributes['text'] := TextEdt.Text;
iNode.Attributes['messwert1'] := Messwert1Edt.Text;
iNode.Attributes['messwert2'] := Messwert2Edt.Text;
iNode.Text := '';
Stream := TMemoryStream.Create; //Stream.size = 0 (logischerweise)
xmlDoc.SaveToStream(Stream); //Stream.size steigt z.B. auf 132
Hashwert := getMd5StreamToStr(Stream);
Ich möchte die
XML.Datei somit z.B. erstmal in den Hauptspeicher laden (Stream), um diesen Stream dann zu hashen. Danach füge ich einen weiteren Knoten "hashdaten" mit dem Hashwert an. Leider ist der berechnete Hashwert stets der selbe, egal, welche Daten das
XML enthält. Habe ich hier vllt noch einen grundsätzlichen Fehler drin? Ich leider bisher noch nie mit Streams gearbeitet.
Für die Berechnung des Hashwertes nutze ich die
Indy-Komponente von Delphi:
TIdHash.HashStreamAsHex
Wenn dieses Problem geklärt ist bleibt noch die Frage, wie ich das ganze dann beim Einlesen bewerkstellige. Denn wenn ich die
XML-Datei wieder einlese habe ich ja auch den Knoten "hashdaten" mit drin. Dieser darf natürlich bei der Berechnung des Hashwertes keine Rolle spielen.
Ich hoffe sehr, dass ich verständlich gemacht habe, wo mein Problem liegt und hoffe auf Rat von euch
. Wahrscheinlich lassen sich beide Probleme schnell und einfach lösen.
Grüße
Headbucket