MD5-Hash bei Java und C# geben nicht das selbe Ergebnis?

3 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

Ich zitiere aus der von dir verlinkten Doku:

Der MD5-Hash wird über die Bytefolge der UTF-16LE-Codierung dieses Strings gebildet (ohne BOM und ohne abschließende 0-Bytes).

Das ist ein bisschen unüblich und macht natürlich einen wesentlichen Unterschied. Dein Java-Code arbeitet nicht so, der in C# schon.


verreisterNutzer  27.09.2020, 14:38

Leider bin ich nicht der Fachmann wenn es um Codierung und Byte To String, bzw String to Hash geht. Ich wäre sehr dankbar, wenn du mir eine Beispiellösung geben könntest oder etwas, was mir hilft, eine Lösung in Java zu finden.

alfredo153  27.09.2020, 14:55
@verreisterNutzer

Der wesentliche Unterschied ist .getBytes(), da müsste sowas rein wie:

byte[] bytes = digest.digest(input.getBytes(StandardCharsets.UTF_16LE));
verreisterNutzer  27.09.2020, 15:02
@alfredo153

Danke dir! Leider nicht das selbe wie beim C#-Code aber ich werde trotzen schauen ob es funktioniert hat. :D

alfredo153  27.09.2020, 15:06
@verreisterNutzer

Wenn du's mit den DigestUtils machst:

DigestUtils.md5Hex(input.getBytes(StandardCharsets.UTF_16LE))

Damit bekomme ich auch 0e9af10abdb7cd7119a85967272e3bc3, wie im C#-Beispiel.

verreisterNutzer  27.09.2020, 15:06
@alfredo153

Leider mag die FritzBox die Response nicht. Es kann aber auch sein, dass ich irgendetwas grundlegend falsch verstehe. Ich schau mir mal die FritzBox Dokumentation genau an. Aber danke für deine Hilfe

Der erste Hash ist voller 2er, die da nicht rein gehören. Woher genau die kommen, musst du selber herausfinden.

Generell würde ich bei solchen Sachen auf Probleme mit ByteOrder oder Zahlenrepräsentation(signed/unsigned) tippen.

(Gerade bei deinem C# beispiel würde ich ersteres prüfen. Zudem, ob die Bytcodierungd es Strings dieselbe ist, wie die in Java. Bei verwendung eines anderen Encodings kann diese variieren.)


verreisterNutzer  27.09.2020, 14:43

Woher die ganzen Zweien kommen weiß ich leider nicht. Ich habe leider von Byte Order oder Zahlenrepräsentation gar keine Ahnung. Wie Java und C# die MD5 Hashes verwaltet, bzw wie die FritzBox den Hash möchte verstehe ich leider fast gar nicht. Du kannst dieses ja auch meinen Schritten herausfinden. Wenn du eine Idee hättest, was ich für einen Java Code schreiben sollte, wäre ich dir / Ihnen sehr dankbar.

Destranix  27.09.2020, 14:50
@verreisterNutzer

In deinem ersten javabeispiel wäre es sicherlich hilfreich, das Encoding beim umwandeln des Inputs in Bytes anzugeben.

Die zweien entstehen mit hoehr wahrscheinlichkeit erst beim ausgeben. Ich vermute, dass das dmait zusammenhängt, dass du eine Weite im Formatstring mit angegeben hast.

alfredo153  27.09.2020, 15:35
@Destranix

Doch, die 0 ist nötig, sonst gibt's unerwünschte Leerzeichen (etwa " a" statt "0a"). Die Syntax ist praktisch identisch mit der von Formatstrings in printf() in C.

Destranix  27.09.2020, 15:41
@alfredo153

Ja, stimmt. Hatte das nur nicht in der Flagliste auf der verlinkten Siete gesehen. Die '0' wird dort wie ein kleines 'o' dargestellt.

In der detailierten Erklärung weiter unten ist die Darstellung allerdings korrekt.

Wenn dein C#-Code für 51cbb71a-Test den MD5-Hash 0e9af10abdb7cd7119a85967272e3bc3 raushaut, dann hast du im C#-Teil irgendeinen Fehler.

Korekt wäre 3ea811b7192d1ae6e1f021b014c169a8.

Interessanterweise ist trotzdem kein Fehler in deinem C#-Snippet zu erkennen, was die Fehlersuche nicht gerade vereinfacht...


Thomas416  27.09.2020, 15:51

Zum Testen kannst du auch einen online-Hashgenerator verwenden, z.B.:

https://www.md5hashgenerator.com/

Er zeigt, dass deine beiden Java-Rechnungen das richtige Ergebnis liefern, der C# Code hingegen nicht.

Den Fehler würde ich am ehesten bei der Berechnung der Hash-Eingabe vermuten:

Encoding.Unicode.GetBytes("51cbb71a-Test")

Das liefert wohl aus irgendeinem Grund nicht (exakt) die richtige Bytefolge. Man muss ja bedenken, dass jede geringfügige Änderung der Eingabe einen völlig anderen Hashwert ergibt.

verreisterNutzer  27.09.2020, 14:20

Komischerweise soll dieser Code aber funktionieren. Hingegen meiner nicht (Java)

alfredo153  27.09.2020, 14:27
@verreisterNutzer

Ich habe den vagen Verdacht, dass der Unterschied in der Umwandlung von String zu Bytes liegt. Etwa hier:

Encoding.Unicode.GetBytes(...)
Isendrak  27.09.2020, 14:28
@alfredo153

Aye, UTF-16 könnte da tatsächlich Probleme machen.

Encoding.UTF8.GetBytes(...)

sollte funktionieren.

alfredo153  27.09.2020, 14:30
@Isendrak

Anscheinend liefert aber der falsche Code das von der Fritzbox gewünschte Ergebnis, wenn ich FS richtig verstehe.

Das Java-Resultat ist jedenfalls im üblichen Sinn richtig, man kann das ja auch mit den vielen Online-MD5-Generatoren überprüfen.

alfredo153  27.09.2020, 14:31
@Isendrak

Aha, der FS hat die verlinkte Doku nicht gelesen:

Der MD5-Hash wird über die Bytefolge der UTF-16LE-Codierung dieses Strings gebildet (ohne BOM und ohne abschließende 0-Bytes).
verreisterNutzer  27.09.2020, 14:36
@alfredo153

Ich habe das gelesen und auch mal mit der UTF-16-LE Codierung ausprobiert. Der Code dafür ergab zuerst Chinesische Symbole und dann ein Ergebnis das Falsch war.