![]() |
Datei sicher löschen
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 ![]() 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:
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.
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) 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:
Delphi-Quellcode:
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.
BlockWrite(f, FillBuffer[j], Buffer);
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:
Ach ja, die Folge der Bufferinhalte scheint auch nicht wahrlos gewählt zu sein:
Delphi-Quellcode:
Da vermute ich mal wieder einen echten Sinn. Leider erschließt sich auch der mir nicht.
FillBuffer: array[0..5] of Integer = ($00, $FF, $00, $F0, $0F, $00);
Wenn mir hier jemand für klare Sicht behilflich sein kann, große Freude. Gruß oki |
Re: Datei sicher löschen
Hmmm ... der Code ist echt übel. Ich würde eine komplette Neuimplementierung empfehlen. Darüber hinaus ist das 35fache Überschreiben totaler Overkill. Bei den heutigen Datendichten reicht ein einzelner Überschreibvorgang aus. Der Mythos des "Restmagnetismus" ist auf moderne Hardware also nicht mehr zutreffend.
Prinzipiell solltest Du auch den Slack Space überschreiben. Das macht die Funktion derzeit nicht. |
Re: Datei sicher löschen
Zitat:
Und jetzt mal ganz blöd gefragt; Was ist der Slack Space :gruebel: Reicht das WriteBlock aus? gruß oki |
Re: Datei sicher löschen
ja, ist sicher ... such mal etwas ... gibt hier schon einige Threads dazu
|
Re: Datei sicher löschen
|
Re: Datei sicher löschen
Zitat:
![]() Zum Thema Slack SpacE: Der Einfachheit halber belegen Dateien bei den meisten Dateisystemen immer eine ganze Anzahl an Clustern (Cluster -> eine Ansamlung von Sektoren). Bei NTFS ist die Clustergröße normalerweise 4 KB (also 8 Sektoren). Also wenn eine Datei nur ein Byte groß ist, belegt sie trotzdem einen Cluster und somit 4 KB. Angenommen die Datei war irgendwann mal größer und wurde dann verkleinert, so befinden sich im Rest des letzten belegten Clusters (Slack Space) noch immer die Daten die dort mal waren. Entsprechend musst Du sicher stellen, daß Du bei Dateien deren Größe nicht zufällig durch die Clustergröße teilbar ist, auf die nächste Clustergrenze aufrundest. |
Re: Datei sicher löschen
Sorry, dass ich so lange nicht rein geschaut habe, war an einem anderen Thread beschäftigt.
Hmmm :gruebel: da muss ich dann doch noch mal ne Runde lesen. Das mit dem Slack Space gefällt mir gar nicht. Gruß oki |
Re: Datei sicher löschen
ja und am Besten auch gleich noch die restlichen unallokierten Cluster und die Slack-Spaces hinter anderen Dateien mit löschst/überschreibst ... deine Datei könnte ja inzwischen verschoben wurden sein und somit noch irgendwo anders Daten der Datei rumliegen (z.B. bei der Defragmentierung und Größenänderung der Datei)
|
Re: Datei sicher löschen
Delphi-Quellcode:
procedure ShredderFile(const filename:string);
const Fillchars: array[0..5] of char = (Char($00), Char($FF), Char($00), Char($F0), Char($0F), Char($00)); BLOCK_SIZE = 8096; var fs : TStream; buffer : String; i, j : Integer; begin fs := TFileStream.Create(filename, fmOpenReadWrite or fmShareExclusive); try // Datei auf nächste Blockgrösse verlängern, damit der "Slack" überschrieben // wird fs.Size := ((fs.Size div BLOCK_SIZE) +2) * BLOCK_SIZE; // Datei soll mindestens 2 MB gross sein, damit die Schreibcaches der // Festplatten überflutet werden if fs.Size < 2097152 then fs.Size := 2097152; for i := 0 to 5 do begin fs.Position := 0; buffer := StringofChar(Fillchars[i], BLOCK_SIZE); for j := 1 to fs.Size div BLOCK_SIZE do begin fs.WriteBuffer(buffer[1], BLOCK_SIZE); end; FlushFileBuffers(fs.Handle); end; // zum Schluss belanglose Daten schreiben buffer := '2g642467894erp46FGHTZ&%%&/&)$%"&$%& 5675645 '; fs.Position := 0; for j := 1 to fs.Size div Length(buffer) do begin fs.WriteBuffer(buffer[1], Length(buffer)); end; finally fs.Free; end; 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 newname := ExtractFilepath(Filename)+'$000000.tmp'; if not RenameFile(Filename, newname) then raise Exception.CreateFmt('Can''t rename file %s', [filename]); ShredderFile(newname); DeleteFile(newname); end; |
Re: Datei sicher löschen
@himitsu: das ist jetzt aber nicht fair :roll: Mich so ins Aus zu schicken. Wie ermittel ich die unalokierten Cluster?
@shmia: Dank für den Code. Das Thema mit den 2 MB ist mir nicht klar geworden. Was ist, wenn ich Dateien mit geringerer Länge habe? Oder soll die Datei künstlich auf 2MB vergrößert werden um den von dir beschriebenen Effekt des "überfluten des Schreibcash" zu erziehlen (was immer das für'n Zauber ist :glaskugel: ). Das Thema unalokierte Cluster ist aber im Code nicht enthalten, somit muss wohl himitsu bluten wenn er noch Lust hat. :stupid: Gruß oki |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz