Hi,
BTW: MD5 sollte mittlerweile als gebrochen angesehen und zu kryptographischen Zwecken nicht mehr benutzt werden.
Dies ist teilweise Unfug.
Es mag dem einem oder anderem als paranoid erscheinen, aber es ist keinesfalls Unfug.
Dennoch ist es schwer, zwei _Sinnvolle_ Nachrichten mit dem gleichen Hashwert zu finden.
Es kommt hierbei auf das Format an:
http://www.cits.rub.de/MD5Collisions/
Deshalb sind kryptographische Hashes bei Text auf den rohen, unformatierten Text anzuwenden. Das bedeutet auch, das die Benutzung von unbekannten Formaten (z.B. ein MS-Word-Dokument) ein Sicherheitsrisiko darstellt.
Die schwache Kollisionsresistenz ist aber weiterhin gegeben, diese besagt: Zu einer gegebenen Nachricht ist es schwer, ein zweite verschiedene mit dem gleichen Hashwert zu finden.
Das ist bei MD5 nicht mehr schwer genug. Insbesondere bei Paßwörtern:
Wäre dies nicht vorhanden, hätte man ein Problem beim Speichern von Passwörtern.
Es gibt tatsächlich ein Problem damit, MD5 ist als Eiweghash nicht mehr zu empfehlen. Es gibt eine großangelegte Aktion, die zu allen möglichen Hashes ein passendes Paßwort sucht, das kann dann nachgeschaut werden anstatt mühselig probiert.
Z.B. bei Dateien die zum Download angeboten werden. (Hexadezimal sinnvoll)
Wenn ich mir ein Programm herrunterlade (z.B. php), und schauen möchte ob dies fehlerfrei Übertragen wurde, dann geh ich auf die Homepage, da findet man oft soetwas:
md5: fb1aac107870f897d26563a9cc5053c0
Auf der gleichen Homepage wo Du es auch herunterlädst? Dann ist sowas eh zweckfrei.
Zudem wäre auch hier zwar base64() sinnvoller, aber es spart nicht viel und ist dem C&P auch egal.
Diese Anwendung würde ich übrigens auch unter meine Ausnahmen "Dokumentation&Debugging" setzen.
Dann starte ich mein altes Dos Programm, gebe den Pfad zu Datei an, dies berechnet den Hashwert und gibt ihn als Hexadezimal aus. Per Auge überprüfe ich ob die Hashwerte identisch sind.
_Mußt_ Du das per Auge überprüfen oder wäre es nicht doch sinnvoller weil fehlerresistenter, diesen Vergleich einen Automaten machen zu lassen? Ich glaube schon.
Angenommen auf der PHP Homepage wäre die Ausgabe als ASCII-String.
Wie wäre es denn mit einem passendem Mimetypen?
Anstatt, wie es bisher ist, folgendes zu benutzen:
printf("%08x%08x%08x%08x",A,B,C,D);
Müsste dieser erst A,B,C,D kodieren. Benutzt man z.B. Base64, dort werden 3 Byte in 4 Byte "überführt". Allerdings besitzt jede Variable 4 Byte/32 Bit.
Den Weg zum "allerdings" verstehe ich nicht.
Und des weiteren hat man ein Problem, wenn das Programm z.B. Base32 benutzt, auf der PHP Homepage aber der Hashwert als Base64 angegeben wird.
Wie gesagt, ein passender Mimetype regelt sowas.
Also das ist ein deutlicher Mehraufwand für Programmierer, außerdem wäre es dann Sinnvoll, wenn MD5 einen Kodierungstandard vorgibt, damit nicht jeder macht was er möchte.
Aber warum benutzt man dann nicht gleich Hexadezimal?
Warum nimmt man denn nicht gleich Base64?
Oder die Rohware mit passendem Mimetypen?
Nein, die Ausgabe als hexadezimalen String bringt keinerlei Vorteile.
Da ist es völlig egal. Wenn es trotzdem Probleme bereitet ist eines der beteiligten Programme kaputt oder schlecht programmiert.
Wenn man z.B. eine .exe Datei im Editor/Notepad öffnet, dort einen Buchstaben einfügt und diesen wieder löscht => speichern, so wird das Programm aufgrund der Steuerzeichen nicht mehr funktionieren.
Dann ist also Notepad beschädigt oder schlecht programmiert. Denn ein Editor, der die geladenen Dateien ohne Auftrag des Benutzer verändert ist nicht zu gebrauchen.
In den von mir benutzten Editoren funktioniert sowas wie von Dir beschrieben übrigens problemlos.
Also könnte man z.B. eine Passwortdatei nicht per Notepad bearbeiten.
Dann laß es doch und nimm das dazu vorgesehene Programm!
Und wenn ich per phpMyAdmin den Datensatz anschaue, dann müssen im Formular auch steuerzeichen dargestellt werden, was zu Problemen führt.
Dann ist das Programm phpMyAdmin zum Anschauen ungeeignet.
Ich benutze hier meist Nedit als Editor, das zur Darstellung und Eingabe von Steuerzeichen in der Lage ist. Warum kann es phpMyAdmin nicht? Kaputt?
Aber wie ich selber schon sagte:
Lösung => Kodierung (warum kein Hexadezimal)
zu Dokumentations und Debuggingzwecken ist eine Codierung als hexadezimalen String genehmigt und auch willkürlicher Quasistandard.
Wo bitte sollte es Verluste geben? Nein, Unfähigkeit des Programmierers ist kein Grund.
Siehe .exe Beispiel.
Ja, das war ein gutes Beipiel, wenn auch nicht in Deinem Sinne.
Ja, das ist wohl wahr und zwar in Dokus und Debuggingsessions. Sonst nirgends. Was soll auch ein Mensch damit sonst anfangen?
Ihn vergleichen?
Das sollte der Mensch tunlichst lassen und ein Programm dafür nutzen. Ausnahme: Debugging.
Ihn evt. selber erstellen?
Das will ich sehen, wie Du auch nur TEA im Kopf berechnest!
Na gut, ich gestehe Dir Papier und Bleistift zu, nicht jedem ist ein gutes Gedächtnis gegeben.
Wenn man ein AdminCP schützen möchte, so überprüft man oft:
if(md5($pw)) == "fb1aac107870f897d26563a9cc5053c0");
Und in base64 wäre es sowas wie
if(md5($pw)) == "+xqsEHhw+JfSZWOpzFBTwA==");
Wäre sogar noch ein wenig kürzer, wie man sieht. Ansonsten rein gar kein Unterschied.
Die "Klartext"-Schreibweise ist auch unnötig, wenn z.B. eine Paßwortdatei benutzt wird, in denen die Hashes aufbewahrt werden. Auslesen erfordert keinerlei menschliches Eingreifen und Umwandeln. Hardcodierte Hashes wie in Deinem Beispiel sollten nicht benutzt werden, sie sind mindestens ein Zeichen schlechten Stils, meist jedoch noch mehr.
In einem Tutorial o.ä. ist sowas natürlich i.O., aber da wären wir wieder bei den beiden Ausnahmen: Dokumentation und Debugging.
Das muss aber alles, evt. Umständlich programmiert werden.
Es ist selten wirklich umständlicher.
Sofern man noch andere Sprachen als PHP kennt, weiß man wie dämlich es ist, verschiedene String Arrays in Base64 zu kodieren, denn dort muss man immer ein vielfaches von 3 Suchen, was nicht immer leicht möglich ist.
Hängst Du Dich jetzt an Embededhardware mit begrenztem Speicher? Da würde ich erst recht die Rohware nehmen, die ist ja immer noch am kleinstem!
Und wenn nicht: base64 ist um einiges kleiner als ein hexadezimaler String, der für jedes Byte, das er darstellt satte zwei Byte Platz benötigt.
Außerdem kann man den Hashwert als Hexadezimal wieder sehr leicht in Integer überführen:
fb1aac107870f897d26563a9cc5053c0
fb1aac10 7870f897 d26563a9 cc5053c0
Und auf Basis dieser Hexadezimal Darstellung kann man dann wieder sehr leicht alle andere Formate erhalten.
Noch einfacher kann ich die Bytes der Rohware in Integer überführen, da sie ja sogar schon meist direkt so geliefert werden. Nur halt bei PHP nicht.
Diese 4/5 Ausgaben werden dann einfach aneinandergehängt, fertig ist der Hashwert..
Der Hashwert ist schon vorher fertig, der muß nicht noch weiter bearbeitet werden.
Hast du schonmal den MD5 Algorithmus _selbst_ programmiert?
Ja, warum?
Der return in PHP sieht wie folgt aus:
return hex($a).hex($b).hex($c).hex($d);
hex(); wandelt dabei Integer in Hexadezimal Darstellung um.
Und wozu? Laß doch das Array mit den 4 Integern, stört doch keinen!
BTW: ich hoffe nicht, das in PHP der MD5-Algorithmus in PHP geschrieben ist. Aber mich wundert bei PHP ja eh schon nicht mehr viel.
Was ist mit denen? Die können damit auch keine Hexadezimalen Zahlen darstellen, also wie kommst Du auf diese Leute?
Die Mathematik ist die einzige Sprache, die international ist. Sowohl ein Deutscher, als auch Japaner kann die Hexadezimaldarstellung Interpretieren, und wieder in die _orginal_ Werte zurücküberführen.
Nun, Du benötigst aber zur Darstellung dieser Hexadezimalzahlen -- die ja als Strings dargestellt werden -- den ASCII Zeichensatz, oder? Den haben sie aber nicht, deshalb können sie auch mit den Hexadezimalzahlen nichts anfangen. Können sie das doch ist Dein Argument, das diese Leute eben jene Hexadezimalzahlen benötigen, da sie kein ASCII können hinfällig.
Das ist nicht sicher, das kannst Du so nicht behaupten. Das kann selbst bei ASCII auch "dcba" oder gar "badc" sein.
Gut das stimmt, es kommt auf die Plattform drauf an. Aber der Wert: 0x61626364 wäre weltweit eindeutig, ganz im gegensatz zu: abcd.
Und wie möchtest Du ihn rüberbringen den Wert 0x61626364? Als Zahl? Dann mußt Du sie kodieren und zwar in etwas in des Nachbarn Zeichensatz. Kein ASCII: keine Hexadezimalzahl -- doch ASCII: "abcd" funktioniert, Hexadezimalzahl ist überflüssig.
Die Buchstaben a,b,c,d,e,f stehen aber nicht für den Wert des ASCII Wertes, sondern für 10,11,12,13,14,15.
Dies ist Weltweit eindeutig.
Das sind aber wiederum keine Hexadezimalzahlen, die Du doch zu verteidigen suchtest!
Was spricht denn gegen die Hexadezimal darstellung?
- Anders als bei einer Kodierung verbraucht der Wert nicht unnötig mehr Platz, denn man kann diese als "Binär" speichern, also braucht er nur 16 Byte anstatt 32 Byte wenn man ihn als ASCII String speichert.
Ah, ich glaube ich verstehe so langsam. Du sitzt einem Trugschluß auf. Die hexadezimale Darstellung _ist_ ein String. Du benötigst also zur Darstellung doppelt soviele Bytes, wie das Original. Um nochmal auf Dein Beispiel weiter oben zurückzukommen:
if(md5($pw)) == "fb1aac107870f897d26563a9cc5053c0");
Hier ist "fb1aac107870f897d26563a9cc5053c0" ein String, keine Zahl! Eine Zahl wäre \xfb1aac107870f897d26563a9cc5053c0, wobei die aber wahrscheinlich zu groß für viele Sprachen wäre da sie 1:1 nur in eine 128 Bit-Architektur passen würde. Ich konnte mir bis hierhin noch keinen 64Bit Rechner leisten, deshalb habe ich mich noch nicht mit den jeweiligen Opcodes bekannt gemacht. Es ist also durchaus möglich, das es dort funktioniert.
- Der Binärwert ist weltweit eindeutig
Ist er nicht, es gibt mehr Architekturen als nur welche mit 2er-Komplement.
- Programmierer können eine Hexadezimal Ausgabe lachhaft einfach realisieren.
Kannst Du es? Bitte beschreibe in einem Satz, wie sowas funktioniert und begründe es in einem weiterem.
- Man muss sich nicht auf ein Kodierungstandard einigen.
Doch, auf den Zeichensatz.
- Man kann ihn sehr leicht in jede weiter Form überführen
Das kann man mit der Rohware auch und hat sich sogar einen Schritt gespart.
Das Hexadezimalsystem eignet sich sehr gut, um Folgen von Bits (verwendet in der Digitaltechnik) darzustellen (Wikipedia)
Ich dachte immer, das wäre mit Nullen und Einsen einfacher?
Aber Scherz beiseite: genau das ist ja eine der von mir beschrieben Ausnahmen, die da lauten: Dokumentation und Debugging.
Tja und MD5 gibt einfach eine Folge von Bits zurück.
Nein, so einfach ist das nicht, da die Reihenfolge je nach Architektur aufbereitet werden muß. Aber ist ja auch völlig egal, denn jede Rückgabe besteht, falls überhaupt vorhanden aus einer Folge von Bits. Ob von MD5(), base64() oder wie die Millionen und Abermillionen von Funktionen, die je geschrieben wurden heißen mögen, die etwas zurückgeben.
so short
Christoph Zurnieden