checksumme für dateien



  • Eine simple Checksumme ist nichts weiter, als die zahl der gesetzten Bits in der Datei. Dies stellt aber nicht sicher, dass nicht bits vertauscht sind.
    Vergleiche die Dateien lieber Byteweise. Das ist sicherer.

    cYa
    DjR



  • Naja, dann dürften die Dateien bei einer 32-Bit Checksumme nicht sehr groß sein wenn du die gesetzten Bits zählst. Ausserdem ist das höllenlangsam und unsicher (hattest du aber schon gesagt).



  • Du könntes ja statt bitts zählen, die einzelnen bytes xor weise verbinen. Das würde mit hoher warscheinlichkeit auch bei vertauschten bits ansprechen. Je groösser man den einzelnen Block nimmt, den man verxorrt dessto sicherrer kann man sich sein (zb eine DWORD BLOCKGROESSE).

    Es gibt noch einen zweiten ansatz, der noch mehr Sicherheit verspricht.
    Man kann die Pruefziffer auch so bilden:
    Wenn ich zu einem char 3 mal 100 dazuzähle kommt irgendeine Wert nach der 256-Uhrenarithmetik heraus. dieser ist aber immer der gleiche. wenn ich von diesem Wert wieder 300 abziehe kommt wieder der ursprüngliche heraus.
    Mann könnte nun also byteweise herauslesen (oder auch word oder dwordweise). Den ersten Wert addiere ich zu meinem derzeitigen Pruefsumme. Den zweiten subtrahiere ich, den dritten addiere ich wieder, ...
    Man kann das Verfahren noch genauer machen, indem man komplizierte Reihenfolgen verwendet, z.B beim Dritten Wert den Doppelten wert nehmen, irgendwo den dreifachen. ...



  • crc32 ist klasse. wesentlich besser als ne dumme bitanzahl.

    md5 ist für kryptographische belange da, also um sicherzugehen, daß ein user nicht böswillig und mit viel mühe ne datei so geändert hat, daß sie die alte checksumme behält.



  • Versuchs mal damit:
    Aufruf:

    unsigned long int result;
    FileCheckSum("Test.dat",&result);
    

    Hier der zugehörige Code

    /***********************************************************************.MA*
    .MODULE [ erzeugen von CRC Checksummen ]
    --------------------------------------------------------------------------
    .FILE	  [ crc.c	    ]	.PROGRAM  []
    .ID       [                 ]   .PART     []
    .REVISION [                 ]
    .AUTHOR   [ PAD	 ]
    .GROUP	  [ tools / general	 ]
    --------------------------------------------------------------------------
    COPYRIGHT : 
    ADDRESS   : 
    --------------------------------------------------------------------------
    Revision Control System Information
    .VERSION   $Revision:$
    .CHANGED   $Author: $
    .DATE	   $Date: 2001/07/19 13:03:38 $
    .LOGFILE   $Source:$
    .STATE	   $State: Exp $
    $Header: $
    --------------------------------------------------------------------------
    .DESCRIPTION
    Description of the functionality can be found in the function headers
    --------------------------------------------------------------------------
    .INDEX
    see functions
    --------------------------------------------------------------------------
    .INHALT
    working CRC Chechsums on Buffers and Files
    --------------------------------------------------------------------------
    .INCLUDE_REFERENCES
    --------------------------------------------------------------------------
    .HISTORY
    
    Revision 1.1  2000/02/28 12:33:30  PAD
    Initial revision
    **********************************************************************.HE**/
    
    #define BUFFERLEN	8192
    #define CRC32_DEFAULT_POLYNOMIAL 0x04c11db7L
    unsigned long crc_table[256];
    
    /*********************************************************************.FA*
    .FUNCTION [ setzen des Polynoms für den CRC32	 ]
    --------------------------------------------------------------------------
    .GROUP	[		  ]
    .AUTHOR [ PAD ]
    --------------------------------------------------------------------------
    .Description
    in dieser Routine wird der Checksummen Acuu vor dem Aufruf der routine
    checksum initialisiert. dies ist nötig, da sonst nicht mehrere Buffer,
    z. B. Files die nicht in einem Stück gelesen werden können, bearbeitet
    werden könnern.
    --------------------------------------------------------------------------
    .Parameter
     INPUT:
     none
     OUTPUT:
     none
    --------------------------------------------------------------------------
    .RETURNVALUE
     none
    --------------------------------------------------------------------------
    .LOCAL_VARIABLES
    --------------------------------------------------------------------------
    .GLOBAL_VARIABLES
       none
    --------------------------------------------------------------------------
    .FUNCTION_REFERENCES
    --------------------------------------------------------------------------
    .History
    Date		Author		     Comment
    19.07.01 08:42	PAD
    *********************************************************************.HE*/
    void  InitCrcCheckSum(unsigned long int *value)
    {
      *value = 0xFFFFFFFFL;
    }
    
    /*********************************************************************.FA*
    .FUNCTION [ berechen der CRC-Tabelle für CRC32 and des Polynoms ]
    --------------------------------------------------------------------------
    .GROUP	[		  ]
    .AUTHOR [ PAD ]
    --------------------------------------------------------------------------
    .Description
    
     Synopsis:
      GenCrcTable() -- generates a 256-word table containing all CRC
    		     remainders for every possible 8-bit byte.	It
    		     must be executed (once) before any CRC updates.
    
      Other degree 32 polynomials may be substituted by re-defining the
      symbol POLYNOMIAL below.  Lower degree polynomials must first be
      multiplied by an appropriate power of x.  The representation used
      is that the coefficient of x^0 is stored in the LSB of the 32-bit
      word and the coefficient of x^31 is stored in the most significant
      bit.	The CRC is to be appended to the data most significant byte
      first.  For those protocols in which bytes are transmitted MSB
      first and in the same order as they are encountered in the block
      this convention results in the CRC remainder being transmitted with
      the coefficient of x^31 first and with that of x^0 last (just as
      would be done by a hardware shift register mechanization).
    
      The table lookup technique was adapted from the algorithm described
      by Avram Perez, Byte-wise CRC Calculations, IEEE Micro 3, 40 (1983).
    
      Author:  Adapted from the CRC used by ethernet
    		       i.e. the 4 bytes frame check sequence as
    		       defined by IEEE 802.3 and implemented by C.M.H
      Date:   Oct-1994
    
    Der Default Aufruf für diese Routine ist GenCrcTable(CRC32_DEFAULT_POLYNOMIAL);
    
    wird dies Routine mit einem value 0 aufgerufen wird automatisch das 
    Polynom CRC32_DEFAULT_POLYNOMIAL benutzt.
    --------------------------------------------------------------------------
    .Parameter
     INPUT:
     unsigned long int value   Wert des zu benutzenden Polynoms
     OUTPUT:
     none
    --------------------------------------------------------------------------
    .RETURNVALUE
     none
    --------------------------------------------------------------------------
    .LOCAL_VARIABLES
    --------------------------------------------------------------------------
    .GLOBAL_VARIABLES
       none
    --------------------------------------------------------------------------
    .FUNCTION_REFERENCES
    --------------------------------------------------------------------------
    .History
    Date		Author		     Comment
    19.07.01 08:42	
    *********************************************************************.HE*/
    void GenCrcTable(unsigned long int value)
     /* generate the table of CRC remainders for all possible bytes */
    {
      register int i, j;
      register unsigned long CrcAccum;
      if (0l==value)
    	  value=CRC32_DEFAULT_POLYNOMIAL;
      for ( i = 0;	i < 256;  i++ )
      {
        CrcAccum = ( (unsigned long) i << 24 );
        for ( j = 0;  j < 8; j++ )
        {
          CrcAccum = (  CrcAccum & 0x80000000L )
          ? ( ( CrcAccum << 1 ) ^ value)
          : ( CrcAccum << 1 );
        }
        crc_table[i] = CrcAccum;
      }
    }
    
    /*********************************************************************.FA*
    .FUNCTION [ Berechnen der Checksumme CRC32 über Buffers ]
    --------------------------------------------------------------------------
    .GROUP	[		  ]
    .AUTHOR [ PAD ]
    --------------------------------------------------------------------------
    .Description
    In dieser Routine wird die CRC Checksumme des Buffers tx_message über
    die vorgegebene Länge length zur bestehenden Checksumme hinzugefügt
    Das ergebnis wird als Return Parameter geliefert
    Soll der CRC nür über den aktuellen Buffer laufen so
    ist InitCrcCheckSum jedesnal vorher aufzurufen
    
     !!!! Achtung  !!!!  Die Buffer müssen in der Länge durch 4 teilbar sein
    
    --------------------------------------------------------------------------
    .Parameter
     INPUT:
     char *tx_message	    Buffer über den die CRC gebildet werden soll
     unsigned long int length
     none
     OUTPUT:
     none
    --------------------------------------------------------------------------
    .RETURNVALUE
     none
    --------------------------------------------------------------------------
    .LOCAL_VARIABLES
    --------------------------------------------------------------------------
    .GLOBAL_VARIABLES
       none
    --------------------------------------------------------------------------
    .FUNCTION_REFERENCES
    --------------------------------------------------------------------------
    .History
    Date		Author		     Comment
    19.07.01 08:42	PAD
    *********************************************************************.HE*/
    unsigned long int   CrcCheckSumC(char *tx_message,unsigned long int length, unsigned long int *value)
    {
      register unsigned long int i, j;
      register unsigned char count = 0;
    
       /* update the CRC on the data block one byte at a time */
      for ( j = 0;	j < length;  j++ )
      {
        i = ( (unsigned int) ( *value >> 24) ^ tx_message[j] ) & 0xff;
        *value = ( *value << 8 ) ^ crc_table[i];
      }
    
      return *value;
    
    }    /* end checksum */
    
    /*********************************************************************.FA*
    .FUNCTION [ Berechnen der Checksumme einer Message CRC32    ]
    --------------------------------------------------------------------------
    .GROUP	[		  ]
    .AUTHOR [ PAD ]
    --------------------------------------------------------------------------
    .Description
    In dieser Routine wird die CRC Checksumme der message tx_message über
    die vorgegebene Länge length erzeugt, d.h die erzeugte CRC ist genau
    über diesen einen Buffer
    
    !!!! Achtung  !!!!  Die Buffer müssen in der Länge durch 4 teilbar sein
    !!!! Achtung  !!!!    GenCrcTable(); muss einaml vorher aufgerufen werden
                        um dann beleibig viele messages mit dem selben
    					CRC Ploynom zu bearbeiten
    
    Das Ergebnis wird als Return Parameter geliefert
    --------------------------------------------------------------------------
    .Parameter
     INPUT:
     char *tx_message	    Buffer über den die CRC gebildet werden soll
     unsigned long int length
     none
     OUTPUT:
     none
    --------------------------------------------------------------------------
    .RETURNVALUE
     none
    --------------------------------------------------------------------------
    .LOCAL_VARIABLES
    --------------------------------------------------------------------------
    .GLOBAL_VARIABLES
       none
    --------------------------------------------------------------------------
    .FUNCTION_REFERENCES
    --------------------------------------------------------------------------
    .History
    Date		Author		     Comment
    19.07.01 08:42	PAD
    *********************************************************************.HE*/
    unsigned long int  CrcCheckSum(char *tx_message,unsigned long int length)
    {
      unsigned long int value;
      InitCrcCheckSum(&value);
      return CrcCheckSumC(tx_message,length,&value);
    }    /* end checksum */
    
    /*********************************************************************.FA*
    .FUNCTION [ Berechnen der Checksumme über eine File	 ]
    --------------------------------------------------------------------------
    .GROUP	[		  ]
    .AUTHOR [ PAD ]
    --------------------------------------------------------------------------
    .Description.
    
      Es wird versucht das file zu öffnen. Falls erfolgreich wird das file in
      Stücken von BUFFERLEN gelesen und über alle Buffer eine Checksumme
      erzeugt. Diese wird dann zurückgeliefert.
      Da im voraus die Länge eines Files nciht durch 4 teilbar ist,
      wird eine zu kurzer Buffer automatisch auf die nächste durch 4 teilbare Zahl
      mot 0x00 aufgefüllt. Der CRC32 wird dann über diesen verlängerten
      Buffer berechnet.
    
      !!!! Achtung !!!! BUFFERLEN muß durch 4 teilbar sein 
    
    --------------------------------------------------------------------------
    .Parameter
     char *file			Name des Files welches zu prüfen ist
    
     OUTPUT:
     unsigned long int *result   checksumme über dieses File
    --------------------------------------------------------------------------
    .RETURNVALUE
     PASS falls erfolgreich
     FAIL falls File nicht accessible
    --------------------------------------------------------------------------
    .LOCAL_VARIABLES
    --------------------------------------------------------------------------
    .GLOBAL_VARIABLES
       none
    --------------------------------------------------------------------------
    .FUNCTION_REFERENCES
      GenCrcTable();
      InitCrcCheckSumC(result);
      CrcCheckSumC
      fopen
      fread
    --------------------------------------------------------------------------
    .History
    Date		Author		     Comment
    19.07.01 08:42	PAD
    *********************************************************************.HE*/
    int FileCheckSum(char *file,unsigned long int *result)
    {
      unsigned long int i;
      char Buffer[BUFFERLEN+1];
      unsigned long int numread;
      FILE *fp;
      GenCrcTable(0);
      InitCrcCheckSum(result);
      if ((fp = fopen(file, "rb")) == NULL)
        return FAIL;
      while (!feof(fp))
      {
        numread = fread( Buffer, sizeof( char ), BUFFERLEN, fp);
        if (0 != (numread % 4))
        {
          for (i=numread;i<BUFFERLEN;i++)
    	Buffer[i]=0x00;
          numread=((numread % 4)+1)*4;
        }
        *result=CrcCheckSumC(Buffer,numread,result);
        if (feof(fp))
          break;
      }
    
      return PASS;
    }
    /*
    * End of file
    */
    

    🙂



  • ...und was spricht nochmal gegen die Verwendung von MD5 für die Checksummengenerierung?

    http://nemesis.sourceforge.net/browse/mod/hash/md5/md5.c.html



  • Descartes schrieb:

    ...und was spricht nochmal gegen die Verwendung von MD5 für die Checksummengenerierung?

    http://nemesis.sourceforge.net/browse/mod/hash/md5/md5.c.html

    Ohne jetzt Messungen durchgeführt zu haben würde ich mal sagen, das ist eine Frage der Geschwindigkeit. Und - wenn ich nur eine Prüfsumme benötige, reicht crc32 vollkommen aus. Man muss ja nicht immer gleich mit der größtmöglichen Variante aufwarten...



  • Es besteht ein Unterschied ob ich dinge verschlüsseln möchte oder aber Datenintegrität garantieren will. Für die Datenintegrität reicht ein CRC32 mehr als aus. mehr wahr nicht gefragt. Soweit ich MD5 auf die schnelle Überblicke ist der Codierungsaufwand nicht klein.

    Die von mit gepostete Lösung ist bei uns seit längerem im Einsatz um die Datenintegrität von Files zu gewährleiten und hat sich bewährt 🙂

    PS. Hattest du schon mal regelmäßig Daten im Bereich einiger 100 MBs automatisch zu prüfen (Time is money 😉 )



  • PAD schrieb:

    Es besteht ein Unterschied ob ich dinge verschlüsseln möchte oder aber Datenintegrität garantieren will.

    MD5 verschlüsselt nicht, sondern erzeugt nur Hashes/Checksummen.
    In /etc/passwd (bzw. in den Shadow Dateien davon) werden bei Linux Systemen nicht die Passwörter, sondern nur die Hashes derselben abgespeichert.

    PAD schrieb:

    Hattest du schon mal regelmäßig Daten im Bereich einiger 100 MBs automatisch zu prüfen (Time is money 😉 )

    Regelmässig noch nicht, aber aus Erfahrung weiss ich dass die Generierung von MD5 Checksummen bei 650MB CD-ROM oder 4,7GB DVD-ROM ISO-Images schon mal eine kleine Weile dauern kann.
    Aber in meinem Fall sollen/müssen es eben MD5 Hashes sein und dann bleibt nur eins: Performance kommt durch Hardware.



  • Descartes schrieb:

    ...und was spricht nochmal gegen die Verwendung von MD5 für die Checksummengenerierung?

    CRC hat mache zauberhafte eigenschaft, die ihn genau gut für integritätstest macht, wenn man davon aus geht, daß fehler gerne als bursts auftreten, das heißt, direkt neben einem fehler ist vielleicht gleich noch ein fehler, dafür drumherum nicht so.
    wo ein bit grund hatte, umzukippen, mag der nachbar mitumgefallen sein, weil die strahlung so groß war, das staubkorn so gruß etc. und irgendwie ist da CRC gut gewappnet dagegen. aber MD5 gar nicht. das hat nen überhaupt anderen zweck. also ist CRC hier schneller UND besser. ist das nicht klasse?



  • Ich frage mich sowieso, warum MD5 von so vielen eingesetzt wird, um eine
    Checksumme zu bilden.

    Das ist nicht Sinn und Zweck von MD5! Genauso wenig ist es Sinn und Zweck von
    MD5, fuer die Authendifizierung eingesetzt zu werden.

    Naja, darf man sich nicht drueber aufregen 😉

    mfg
    v R



  • virtuell Realisticer schrieb:

    Ich frage mich sowieso, warum MD5 von so vielen eingesetzt wird, um eine
    Checksumme zu bilden.

    Das ist nicht Sinn und Zweck von MD5! Genauso wenig ist es Sinn und Zweck von
    MD5, fuer die Authendifizierung eingesetzt zu werden.

    Und was ist deiner Meinung nach der Sinn und Zweck von MD5?

    Wie CERT schon schreibt:

    http://www.cert.org/security-improvement/implementations/i002.01.html

    Using MD5 to verify the integrity of file contents

    The MD5 program generates a unique, 128-bit cryptographic message digest value derived from the contents of a file. This value is considered to be a highly reliable fingerprint that can be used to verify the integrity of the file's contents. If as little as a single bit value in the file is modified, the MD5 checksum for the file changes. Forgery of a file in a way that causes MD5 to generate the same result as that for the original file is considered to be extremely difficult.

    A set of MD5 checksums for critical system, application, and data files provides a compact way of storing information for use in periodic integrity checks of those files.

    Details for the MD5 cryptographic checksum program are provided in RFC 1321. Source code and additional information are available via FTP from ftp://ftp.cerias.purdue.edu/pub/tools/unix/crypto/md5



  • Descartes schrieb:

    Und was ist deiner Meinung nach der Sinn und Zweck von MD5?

    MD5: Sicherung der Integrität gegen menschliche bewußte böswillige Angriffe.

    CRC: Sicherung der Integrität gegen gegen zufällige technische Fehler.

    If as little as a single bit value in the file is modified, the MD5 checksum for the file changes.

    Das macht sogar ne schlichte Summe. Einzelbitfehler sind zu einfach. Mehrbitfehler sind das Gebiet, wo CRC besser ist, als stupide Summen.

    Forgery of a file in a way that causes MD5 to generate the same result as that for the original file is considered to be extremely difficult.

    Gegen menschen!



  • @PAD

    Hattest du schon mal regelmäßig Daten im Bereich einiger 100 MBs automatisch zu prüfen

    Wie sieht denn sowas in der Praxis aus ? Wird für jede "Original"-datei eine separate *.crc32 Datei angelegt und dann später mit der errechneten Checksumme verglichen oder speichert man das in einer Liste und sucht dann die Liste immer wieder durch nach dem entsprechenden CRC Wert ?

    Gruß WoWe



  • In einem ersten Lauf wird für alle zu überprüfenden Dateien eine Datei (Soll.crc) angelegt in der die Filenamen und die zugehörigen Checksummen stehen. Danach wird eine Datei (sum.crc) erzeugt, die die Checksumme über soll.crc Datei enthält.

    Bei der Überprüfung werden dann die ermittelten Checksummen in einer temporären Datei ist.crc ermittelt. Die Checksumme über diese Datei wird gebildet isum.crc und mit dem Wert aus dem Definitionslauf soll.crc verglichen.

    Bei Diskrepanzen werden die beiden Checksummendateien soll.crc und ist.crc verglichen um den/ die Kandidaten mit dem Fehler zu ermitteln. 😃



  • Hier habe ich durch Zufall noch eine Quelle für CRC32 entdeckt.

    http://www.codeproject.com/cpp/crc32.asp



  • Hallo PAD,

    hab da nochmal ne Frage dazu. In welchen Zeitabständen (vor jedem Backup?) macht ihr solch ein CRC Check und mit welchen Dateien (alle oder nur Verzeichnisse mit "Eigenen Dateien") ?

    Gruß WoWe



  • Die Arbeit hat weder mit Windows noch mit Backup zu tun.

    Wir benutzen es um zu überprüfen ob die auf einem lokalen PC geladene Version
    intakt ist und mit der im Netzwerk bereitgestellten Version der SW übereinstimmt.

    Überprüfung der Intaktheit, dient der Sicherstellung das unsere Produkte mit einer ungeänderten Version der TestSw geprüft werden.

    Überprüfung gegen Netzwerkversion, Sicherstellen das mit der neuesten zugelassenen Softeware getestet wird.



  • Hi,
    @PAD
    ich bekomme keinen CRC werte wie z.B. "5294c29a" sondern ich bekomme "16" zurück ;-(( was könnte ich falsch gemacht haben??
    Ich habe deinen Code in eine Klasse MyCRC gepankt aber an dem darf es ja nicht liegen oder??
    von result müsste man die fertige CRC32-Sum entgegenehemen dueren oder?? Was wird dann dann von der Function zurückgegeben ist nämlich das gleiche.

    Danke dir trotzdem fuer den super Code.

    mfg
    wdsl



  • @wdsl Da ich nicht weis was du wie gemacht hast, weis ich auch nicht was du wie falsch gemacht hast.

    Funktioniert den der C-Code???

    Wenn ja ist es eine Fehler in deiner C++ Umsetzung.


Anmelden zum Antworten