C# MD5 Create, unterschiedliche md5

denn1995

Cadet 1st Year
Dabei seit
Mai 2011
Beiträge
9
Hallo Leute,

Ich bin gerade dabei einen Updater für mein Programm zu erstellen, dort nutze ich eine MD5 verschlüsselung.
Mein Problem ist jetzt, das der MD5 Creator ein anderen Wert als Programme wie z.B. WinMD5Free

Hier der Code, wo die MD5 erstellt wird.
Code:
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace SharpUpdate
{
    /// <summary>
    /// The type of hash to create
    /// </summary>
    internal enum HashType
    {
        MD5,
        SHA1,
        SHA512
    }

    /// <summary>
    /// Class used to generate hash sums of files
    /// </summary>
    internal static class Hasher
    {
        /// <summary>
        /// Generate a hash sum of a file
        /// </summary>
        /// <param name="filePath">The file to hash</param>
        /// <param name="algo">The Type of hash</param>
        /// <returns>The computed hash</returns>
        internal static string HashFile(string filePath, HashType algo)
        {
            switch (algo)
            {
                case HashType.MD5:
                    return MakeHashString(MD5.Create().ComputeHash(new FileStream(filePath, FileMode.Open)));
                case HashType.SHA1:
                    return MakeHashString(SHA1.Create().ComputeHash(new FileStream(filePath, FileMode.Open)));
                case HashType.SHA512:
                    return MakeHashString(SHA512.Create().ComputeHash(new FileStream(filePath, FileMode.Open)));
                default:
                    return "";
            }
        }

        /// <summary>
        /// Converts byte[] to string
        /// </summary>
        /// <param name="hash">The hash to convert</param>
        /// <returns>Hash as string</returns>
        private static string MakeHashString(byte[] hash)
        {
            StringBuilder s = new StringBuilder(32);

            foreach (byte b in hash)
                s.Append(b.ToString("X2").ToLower());

            return s.ToString();
        }
    }
}

Mit diesem Code, kommt z.B. die MD5 (fcc6df49d856c42262d0aeba505179d6) heraus.

Mit dem WinMD5Free kommt z.B. die MD5 (59be6536575fd1b65e21b59f03a85dcc) heraus.

Ich hoffe so sehr, dass mir hier jemand helfen kann.
Vielen Dank!
Dennis
 
MD5 ist keine Verschlüsselung!

Ist der Hexstring den HashFile() zurückgibt korrekt?
 
Das ganze sieht so aus, sollte alles richtig sein.

Code:
        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            string file = ((string[])e.Argument)[0];
            string updateMD5 = ((string[])e.Argument)[1];

            // Hash the file and compare to the hash in the update xml
            if (Hasher.HashFile(file, HashType.MD5).ToLower() == updateMD5.ToLower())
                e.Result = DialogResult.OK;
            else
                e.Result = DialogResult.No;
        }
 
MD5 gilt als kryptographisch unsicher, bitte nicht zur "verschlüsselung" verwenden, zu Validierungszwecken ist MD5 ok.

Habs gerade mal mit nem Standardtext ("Franz jagt im komplett verwahrlosten Taxi quer durch Bayern") geprüft, deine implementation arbeitet imho korrekt (erzeugt a3cca2b2aa1e3b5b3b5aad99a8529074)

Von daher ist die andere Baustelle Input. Du liest etwas anderes als WinMD5Free, da WinMD5Free nicht OpenSource ist kann man schlecht sagen, was wo falsch läuft
 
Also sollte ich die MD5 z.B. in einer MessageBox, über einen separaten Button öffnen und anzeigen lassen.
Das wäre ja die einfachste Lösung.

Ich probiere es gleich mal aus :)
 
Oder ordentliche Debugger-Arbeit: Breakpoint auf die Vergleichszeile, dann kannst Du die linke Seite und die rechte Seite im Visual Studio schön gegenüberstellen.

Zum kryptographischen Part, md5 ist hier, denke ich, i.O., als Signatur taugt es halt nicht, da es nur ein Hash und keine Signatur ist. Außerdem ist Dein Anwendungsfall hier etwas seltsam, zum Verifizieren der Datei-Integrität hat sich eher CRC16/CRC32 durchgesetzt (kann nämlich, im Gegensatz zu md5, Fehler auch reparieren).
 
Zuletzt bearbeitet:
ich habe selbst mal alle hashsummen durchprobiert um den schnellsten zu finden, hatte das selbe problem.

wahrscheinlich liest du nur die ersten 512kb ein, statt die ganze datein.
 
CRC kann Fehler korrigieren? Das ist mir neu. Fehlerkorrekturcodes sind eher so Dinge wie Reed-Solomon-Codes. Die sind aber wesentlich komplexer als CRC.
 
Für Dateivergleiche hat sich md5 "durchgesetzt", aber seit Kollisionen praktisch sind, wird es mehr und mehr durch einen SHA Hash ersetzt. crc32 ist lang lang deprecated weil eben nur 32 bit. Das kann ein RPi im Schlaf kollidieren :) CRC32 ist 1990.
 
Zitat von asdfman:
Einfache Fehler schon (so Kategorie Einbit-Fehler, auch viele Zweibit-Fehler usw.; im Grunde hat man ja hier - mathematisch gesehen - ein relativ simples Polynom). Und es solltesich halt auch einfach in Hardware implementieren lassen. Und damit meine ich Hardware von vor Jahrzehnten.

Das ist mir neu. Fehlerkorrekturcodes sind eher so Dinge wie Reed-Solomon-Codes. Die sind aber wesentlich komplexer als CRC.
Dementsprechend funktioniert da die Fehlerkorrektur auch besser.
Ergänzung ()

Zitat von HominiLupus:
Für Dateivergleiche hat sich md5 "durchgesetzt", aber seit Kollisionen praktisch sind, wird es mehr und mehr durch einen SHA Hash ersetzt. crc32 ist lang lang deprecated weil eben nur 32 bit. Das kann ein RPi im Schlaf kollidieren :) CRC32 ist 1990.
Der Sinn bei CRC ist auch Fehler bei der Signalübertragung zu erkennen und nicht die Integrität der Daten zu gewährleisten.
CRC und md5/SHA-x/usw. haben zwei völlig verschiedene Anwendungsgebiete.

Gruß
Andy
 
Zuletzt bearbeitet:
Zitat von asdfman:
Alles? Gib mir doch wenigstens das relevante Kapitel. Ctrl-f "correct" gab mir nur eine Quellenangabe ganz am Ende. :/
Ähm wie schon gesagt, CRC ist ja letztlich nix anderes als ein Polynom.
Wir haben es hier also mit simpelster Mathematik zu tun.

Nehmen wir an, wir haben die Bitfolge 1001
Dann wäre unser Polynom: 1x³+0x²+0x+1x⁰
Oder kurz: x³+1

Das wird (jetzt ganz einfach gesprochen) geteilt durch ein Polynom, welches Sender und Empfänger bekannt ist und verschickt. Damit sollte eigentlich klar sein, dass zumindest bei einfachen Fehlern sie diese Bits "zurückrechnen" lassen.

Eigentlich simple Mathematik. Und im Paper steht ja eigentlich auch alles dazu drin.

Gruß
Andy
 
Ich weiß, was CRC macht. Dafür muss ich keinen kilometerlangen Artikel lesen.

Zitat von andy_m4:
[...]Damit sollte eigentlich klar sein, dass zumindest bei einfachen Fehlern sie diese Bits "zurückrechnen" lassen.
Nein, das ist mir überhaupt nicht klar. Vielleicht kannst du es mir ja an einem Beispiel erläutern?

Der einfachste Fehler, der mir einfällt, wäre ein 1-Bit flip. Folgendes Programm macht das:
Code:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    FILE *fp;
    int fsize, offs, c;

    if(argc != 2) {
        fprintf(stderr, "USAGE: %s <FILENAME>\n", argv[0]);
        return EXIT_FAILURE;
    }

    if((fp = fopen(argv[1], "r+")) == NULL) {
        fprintf(stderr, "ERROR: fopen(%s) failed.\n", argv[1]);
        return EXIT_FAILURE;
    }

    fseek(fp, 0, SEEK_END);
    fsize = ftell(fp);

    srand(time(NULL));
    offs = rand() % fsize;

    fseek(fp, offs, SEEK_SET);
    c = fgetc(fp);

    printf("Changed LSB at offset: 0x%08x ", offs);
    printf("from %d ", c & 0x01);
    c ^= 0x01;
    printf("to %d\n", c & 0x01);

    fseek(fp, offs, SEEK_SET);
    fputc(c, fp);

    fclose(fp);
    return EXIT_SUCCESS;
}

Habe eine Beispieldatei erstellt:
crc-challenge.png

DOWNLOAD: data.bin

Erklär mir bitte, wie man "zurückrechnet", wo sich der Fehler befindet und wie man ihn korrigiert. Am besten mit Codebeispiel.

Ich habe einen unzensierten Screenshot und die Originaldatei, die ich posten kann, um dein Ergebnis zu verifizieren.
 
Zuletzt bearbeitet:
Hier hast du die Datei wieder mit gleichem CRC (9f07609e): data2.bin

Wenn du dir den Unterschied anschaust siehst du wie ich es gemacht habe, leider aber nicht mit Fehlerkorrektur durch CRC.
Ich bin nämlich bei dir, das ist nicht möglich. Zumindest nicht bei Input größer als der generierte CRC.

Gruß
BlackMark
 
Zitat von asdfman:
Nein, das ist mir überhaupt nicht klar. Vielleicht kannst du es mir ja an einem Beispiel erläutern?
Aufgrund Deines Beitrages ist mir klar geworden, wo dass Missverständnis liegt.

CRC32 ist tatsächlich mehr oder weniger eine reine Prüfsumme die nur darauf ausgelegt ist (bestimmte) Fehler zu erkennen.

Bei dem CRC an das ich gedacht habe, wie es auch üblicherweise bei der Signalübertragung (Bluetooth; oder auch bei Disketten/Festplatten) eingesetzt wird, werden die Nutzdaten tatsächlich kodiert, so dass hinten raus nicht nur eine Prüfsumme raus kommt, sondern quasi die kodierten und mit Redundanz (wenn man so will Paritätsbits) versehenden Daten zur Fehlererkennung und ggf. wenn möglich Korrektur.

Also quasi sehr ähnlich zu dem von Dir angesprochenen Reed-Solomon-Code.

Ich verbuche es mal unter mein Fehler, weil ich nicht ganz realisiert hab, dass zuvor von CRC-16 und CRC-32 gesprochen wurde.

Gruß
Andy
 
Zurück
Top