[C]Datei schredder



  • Hi,

    da ich mal wieder etwas C üben wollte (bin noch Anfänger), habe ich mal ein kleines Programm zum (sicheren?) löschen von Dateien geschrieben.
    Es überschreibt die Datei 35mal mit Zufallsdaten aus /dev/urandom dann einmal mit Nullen und löscht dann die Datei.
    Meine Frage ist nun, ob die Daten aus der Ursprungsdatei dann auch wirklich weg sind?

    Ich kenne mich da nicht so gut aus, aber hat das Dateisystem auch einen Einfluß darauf, ob die Daten dann wirklich von der Platte sind?
    Bei Flash Speichern ist das ja auch wieder was ganz anderes. Wie sieht es z.B. aus wenn ich mit dem Programm Dateien von einem USB Stick (vfat) oder einer SSD lösche?

    vielleicht kann mir das ja jemand mal so grob sagen. 😉

    #include <stdio.h>
    #include <stdlib.h>
    
    void usage(void)
    {
        printf("\nusage: nuke <Ziel Datei>\n");
        printf("\nExample: nuke test.txt\n\n");
    }
    
    int main (int argc, char *argv[]) 
    {
        char ch;
        int i, n=35;
        FILE *target, *random;
    
        if (argc != 2)
        {
            usage();
            return EXIT_FAILURE;
        }
    
        /* open target file */
        if((target = fopen(argv[1], "rb+")) == NULL)
        {
            perror("Fehler beim oeffnen: ");
            return EXIT_FAILURE;
        }
    
        /* open /dev/urandom */
        if((random = fopen("/dev/urandom", "rb")) == NULL)
        {
            printf("Konnte /dev/urandom nicht oeffnen!\n");
            return EXIT_FAILURE;
        }
    
        for(i=0; i<n; i++)
        {
            printf("Ueberschreibe %s mit Zufallsdaten: Durchgang %d/%d\n",argv[1],i+1,n);
            fseek(target,-1L,SEEK_END); /* setze Zeiger auf letztes Zeichen */
            ch = fgetc(random);
            while(1)
            {
                fputc(ch,target);
                if( fseek(target,-2L,SEEK_CUR) !=0 ) /* Datei Anfang erreicht? */
                {
                    break;
                }
                ch = fgetc(random);
            }
        }
    
        /* datei nullen */
        printf("ueberschreibe %s mit Nullen\n",argv[1]);
        fseek(target,-1L,SEEK_END); /* setze Zeiger auf letztes Zeichen */
        while(1)
        {
            fputc('\0',target);
            if( fseek(target,-2L,SEEK_CUR) !=0 ) /* Datei Anfang erreicht? */
            {
                break;
            }
        }
    
        fclose(target);
        fclose(random);
    
        /* Ziel Datei loeschen */
        printf("Loesche %s\n",argv[1]);
        if(remove(argv[1]) == -1)
        {
            perror("Fehler beim loeschen: ");
            return EXIT_FAILURE;
        }
    
        return EXIT_SUCCESS;
    }
    

    p.s.
    Gibt es da evtl. eine elegantere Lösung als meine mit fseek und while schleife?


  • Mod

    sadmarvin schrieb:

    Hi,

    da ich mal wieder etwas C üben wollte (bin noch Anfänger), habe ich mal ein kleines Programm zum (sicheren?) löschen von Dateien geschrieben.
    Es überschreibt die Datei 35mal mit Zufallsdaten aus /dev/urandom dann einmal mit Nullen und löscht dann die Datei.

    Warum 35x und nicht nur 1x? Soll das die Unterstützung für Granittafeln als Speichermedium sein? Glaub nicht jeden Mythos, sonden informiere dich.

    Meine Frage ist nun, ob die Daten aus der Ursprungsdatei dann auch wirklich weg sind?

    Kommt drauf an. Siehe unten. Du hast selber die Probleme erkannt.

    Ich kenne mich da nicht so gut aus, aber hat das Dateisystem auch einen Einfluß darauf, ob die Daten dann wirklich von der Platte sind?

    Ganz sicher hat es das. Die Vielfalt an Dateisystemen ist jedoch sehr groß. Bei den üblichen ext?-Systemen sollte es aber keine Überraschungen geben, sofern du sicher stellst, dass die Daten vor dem Löchen der Datei auch tatsächlich geschrieben werden. Weiß gerade nicht auswendig, wie das genau ging, sollte sich aber leicht rausfinden lassen.

    Bei Flash Speichern ist das ja auch wieder was ganz anderes. Wie sieht es z.B. aus wenn ich mit dem Programm Dateien von einem USB Stick (vfat) oder einer SSD lösche?

    Da wird es noch komplizierter. Denn unter dem Dateisystem kommt noch der Controller der Hardware. Und bei SSDs speichern die neue Daten gerne an anderen Stellen, um die Lebensdauer zu erhöhen. Ich kann dir aber bloß bestätigen, dass dies ein Problem ist, nicht wie du es behebst - dies liegt jenseits meiner Erfahrung. Da musst du dich selber mal kundig machen. Und allgemein kann unterhalb des Dateisystems noch eine Menge passieren, was dir in die Quere kommt. Vertrauen würde ich deinem Programm (nachdem du sichergestellt hast, dass die Daten auch geschrieben werden) nur im Falle einfacher Festplatten. Schönerweise deckt dies bereits den Großteil der Nutzungsszenarien ab.



  • hab irgendwo (bei c't, etc.) gelesen, dass "shreddern" unnötig ist. Einmal überschreiben reicht. Wichtig sei nur, dass man nicht noch irgendwo schattenkopien etc. hat.



  • Wenn es dich wirklich interessiert, wie du die Datei zuverlässig überschrieben bekommst (1x mit Zufallszahlen, danach löschen reicht völlig. Zumindest wenn die Festplatte jünger als 10 Jahre alt ist), dann spick einfach ein wenig in den Quelltexten von dd aus den CoreUtils. 😉

    Ferner die Frage: Warum schreibst du a) rückwärts und b) in einer Endlosschleife? Wie wäre es mit do-while ?

    @SeppJ: Überraschungsfrei wird damit ein ext*-System nur, wenn es ohne Journaling läuft.


  • Mod

    Yamakuzure schrieb:

    @SeppJ: Überraschungsfrei wird damit ein ext*-System nur, wenn es ohne Journaling läuft.

    Aber wenn man ein fsync() macht, bevor man die Datei schließt und löscht, dann sollten doch die Daten wirklich physikalisch überschrieben werden, Journaling hin oder her?!?





  • @Seppj:

    http://de.wikipedia.org/wiki/Gutmann-Methode schrieb:

    Des Weiteren benutzen moderne Dateisysteme das so genannte Journaling, wodurch ein Benutzer nicht wissen kann, wo seine Daten geschrieben werden, so dass ein garantiertes Überschreiben der Datenblöcke einer Datei (ohne weitere Kernelerweiterungen) unmöglich ist. Dieses Problem tritt jedoch nur auf, wenn Dateien eines gemounteten Dateisystems gelöscht werden sollen. Eine komplette (nicht gemountete) Partition oder Festplatte zu löschen ist hingegen durchaus möglich.

    Ein fsync() bringt hierbei nur, dass gecachte Daten auf die Platte geschrieben werden. Wo ist aber fraglich wenn die PArtition/Platte gemountet ist. Ist sie es nicht, braucht man auch keinen Sync.;)

    @rüdiger, Zu der Gutmann Methode:

    http://de.wikipedia.org/wiki/Gutmann-Methode schrieb:

    Diese Methode ist sehr zeitaufwändig, gilt aber für Festplatten, die noch kein PRML oder EPRML verwenden, als die sicherste Methode der softwaregesteuerten Datenlöschung. Dies sind in der Regel Festplatten bis spätestens zum Herstellungsdatum 2001 bzw. bis höchstens 15 GB Kapazität.

    Dies ist der Hintergrund, warum ich schrieb, dass die Festplatte jünger als 10 Jahre ist.

    Grundsätzlich geht es darum, eine Datei unrekonstruierbar zu machen. Die Frage ist, wofür. Wenn es nur darum geht, dass "r-undelete", "magicrescue", "extundelete" und Co diese Datei nicht wiederherstellen können, reicht ein einmaliges Überschreiben durchaus. Das ist besonders dann der Fall, wenn das Dateisystem in häufigem schreibendem Gebrauch ist, und über wenig freien Speicherplatz verfügt.
    Sollen die Daten soweit vernichtet werden, dass es auch mit professioneller Software unter Laborbedingungen nicht möglich ist, die Daten widerherzustellen, dann sind natürlich mehr Durchgänge empfehlenswert.



  • Yamakuzure schrieb:

    Sollen die Daten soweit vernichtet werden, dass es auch mit professioneller Software unter Laborbedingungen nicht möglich ist, die Daten widerherzustellen, dann sind natürlich mehr Durchgänge empfehlenswert.

    In den Wikipedia-Artikeln steht aber, dass genau das gerade eben nicht nötig ist bei halbwegs aktuellen Festplatten: http://en.wikipedia.org/wiki/Data_erasure#Number_of_overwrites_needed

    Wenn man den psychologischen Faktor in Betracht zieht, dann sind natürlich mehrere Durchgänge nötig.


Anmelden zum Antworten