Thema: Delphi Datei sicher löschen

Einzelnen Beitrag anzeigen

oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#1

Datei sicher löschen

  Alt 9. Jun 2009, 14:04
Hallo Leute,

ich schau mal gerade quer Beet, was es so an Code-Snippes zum Thema sicheres Löschen von Dateien gibt. Sinn ist es, eine eigene Funktion dafür zu implementieren.
Natürlich bin ich bei den Jedis fündig geworden. Aber auch im SwissDelphiCenter, siehe hier sicheres Löschen . Auf den ersten Blick sah der Code gegenüber den Jedis um Längen simpler aus. Eigentlich erschien er mir auch nicht weniger sicher. Bei genauerem Hinschauen musste ich aber feststellen, dass der imho ziemlich buggy ist.

Ich möchte hier noch mal den Code posten und die aus meiner Sicht vorhandenen Fehler und Problemstellen kommentieren. Ziel der Übung soll es sein daraus einen ordentlichen Code zu machen. Ich hoffe mit eurer Hilfe. Er soll sicher und einfach sein.

Delphi-Quellcode:
procedure ShredderFile(FileName: string);
const
  Buffer = 1024;
  Counttowrite = 34;
  FillBuffer: array[0..5] of Integer = ($00, $FF, $00, $F0, $0F, $00);
var
  arr: array[1..Buffer] of Byte;
  f: file;
  i, j, n: Integer;
begin
  AssignFile(f, FileName);
  Reset(f, 1);
  n := FileSize(f);
  for j := 0 to Counttowrite do
  begin
    for i := 1 to n div Buffer do
    begin
      BlockWrite(f, FillBuffer[j], Buffer);
    end;
  end;
  CloseFile(f);
  RenameFile(FileName, ExtractFilepath(FileName) + '$000000.tmp');
  DeleteFile(ExtractFilepath(FileName) + '$000000.tmp');
end;

procedure ShredderAndDeleteFile(const FileName: string);
var
  newname: string;
begin
  // zuerst umbennen, dann später keine Rückschlüsse auf den Dateinamen möglich sind
  // first rename the file
  newname := ExtractFilepath(FileName) + '$000000.tmp';

  if not RenameFile(FileName, newname) then
    raise
    Exception.CreateFmt('Fehlercode 2: Kann %s nicht umbenennen!', [FileName]);

  ShredderFile(newname);

  DeleteFile(newname);
end;


// Aufruf / Call: ShredderAndDeleteFile(Edit1.Text)
Erst mal die groben Sachen. Die procedure ShredderAndDeleteFile ruft die Procedure ShredderFile auf. In ShredderFile wird die Datei gelöscht. Das gleiche versucht ShredderAndDeleteFile aber nach der Rückkehr auch noch einmal. Das ist imho Unfug und wirft sowieso eine Fehlermeldung.
Ich würde den Teil für AssignFile in ShredderFile in einen Try finally Block setzen um die Datei sicher mit CloseFile wieder zu schließen. Läuft in der Mitte irgentwas schief, das eine Exception wirft, hat man ruckzuck ein offenes Dateihandle.

So, nun die richtigen Probleme.

Ich interpretiere den Code so, dass die Datei 35 x überschrieben werden soll, bevor sie gelöscht wird. Das ist mal ok.
Das Überschreiben soll in 1k-Blöcken erfolgen (denke ich an der Konstanten Buffer und deren Benutzung in WriteBlock erkennen zu können). Die Maske für die zu schreibenden Blöcke soll sicher FillBuffer liefern. Warum jetzt FillBuffer 6 Integer-Werte hält, was einer Recordlänge von 24 Byte enspricht ist mir überhaupt nicht klar. Zudem ist die Buffergröße von 1024 nicht einmal sauber durch 24 teilbar.
Dann wird ein Array arr als Variable definiert, kommt aber nie zum Einsatz. Bei der kann ich noch die Verwendung erahnen, soll mit der Länge von 1024 (Buffer) sicher die Daten für den Schreibblock halten und müßte somit kontinuierlich mit FillBuffer aufgefüllt werden. Wird halt nur nicht benutzt.
Völlig undurchsichtig wird die Sache aber in der Zeile:
   BlockWrite(f, FillBuffer[j], Buffer); Hier sollen sicher 1024 Byte (Buffer) an die aktuelle Position in der Datei geschrieben werden. Als Vorlage wird hier aber FillBuffer mit einer max. Länge von 24 Byte verwendet. Welchen tieferen Sinn die Angabe von FillBuffer[j], also dem Schleifenzähler der Überschreibvorgänge haben soll ist mir völlig unverständlich. Das j auch über die Grenzen von FillBuffer läuft muss eigentlich nicht erwähnt werden.

Normalerweise würde ich hier sagen "Käse" und gut. Erstaunlicherweise ist es aber so, dass das 35 malige Überschreiben einer Datei als sicheres Löschen angesehen und hier genau so verendet wird:
Zitat:
Als eine der sichersten Methoden des Überschreibens gilt das so genannte Gutmann-Verfahren. In seinem Papier "Secure Deletion of Data from Magnetic and Solid-State Memory" forderte der Sicherheitsexperte Peter Gutmann, zu löschende Dateien gleich 35-mal zu überschreiben.
Somit hatte ich auf den ersten Blick Kompetenz vermutet. Nach lesen des Codes jedoch eher das Gegenteil. Nun gibt es ja noch die Variante, dass ich der arogante Unwissende bin und heimlichen tiefsinnigen Tücken hinter dem Code nicht auf die Schliche komme. So ist arr als Variable mit einer Länge von 1024 Byte direkt hinter FillBuffer definiert. Der trickige Progger könnte ja jetzt vermuten, dass das Lesen über die Grenzen von FillBuffer zu einem Lesen der Werte in arr führt, das diese Bereich ja genau danhinter kommt ; Man kann ja nie wissen.

Ach ja, die Folge der Bufferinhalte scheint auch nicht wahrlos gewählt zu sein:
  FillBuffer: array[0..5] of Integer = ($00, $FF, $00, $F0, $0F, $00); Da vermute ich mal wieder einen echten Sinn. Leider erschließt sich auch der mir nicht.

Wenn mir hier jemand für klare Sicht behilflich sein kann, große Freude.

Gruß oki
42
  Mit Zitat antworten Zitat