Einzelnen Beitrag anzeigen

Headbucket

Registriert seit: 12. Dez 2013
Ort: Dresden
172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

XML-Datei zu Stream | Stream zu Hashwert | XML gegen Manipulation schützen

  Alt 12. Dez 2013, 11:19
Delphi-Version: XE5
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: Delphi-Referenz durchsuchenTIdHash.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
  Mit Zitat antworten Zitat