Jörg Reinholz: Kleine Bibliothek für Passwort-Hash-Erzeugug und Verifizierung

Beitrag lesen

Moin!

Naja. Das Vorhanden sein von openssl_random_pseudo_bytes() könnte man mit function_exists('openssl_random_pseudo_bytes') prüfen. Ich schlage dennoch nach den Hinweisen von United Power und Felix als Kompromiss vor, mt_rand() zu nutzen.

Grund: openssl_random_pseudo_bytes() liefert nämlich überwiegend Bytes welche nicht in dem für diverse Salts gültigem Bereich liegen (insbesondere auch: nicht druckbare). Von 253 möglichen Bytes (ich nehme mangels Dokumentation an, EOT, EOF und NUL werden aus gutem Grund nicht geliefert) sind (je nach Hash-Verfahren) nur 36, 62 oder 64 in Salts gültig. Die anderen müsste man aussortieren. Klar: auch das ist machbar. Nur holt man dann im Durchschnitt (bei 64 gültigen Zeichen) ungefähr 88 Bytes ab um einen 22-Zeichen starken, gültigen Salt zu haben. Das klingt "teuer".

Weitere Erläuterungen (welche meine "Vorredner" inhaltlich gewiss schon kennen): Bei den Salts kommt es nicht so sehr auf optimalen Zufall an wie bei richtiger Kryptographie. Das Salzen und Hashen in mehreren Runden soll bewirken, dass ein Angreifer - der die Nutzernamen und die Hashes bereits hat (also Rundenzahl und Salts sogar kennt) - die Passwörter nachfolgend nicht einfach mit Rainbow-Tables oder aus einer schlichten Datenbank ermitteln und für den Angriff auf weitere Systeme (das, woher er die Daten hat, ist oft bereits vollständig "erlegt") nutzen kann. Das Verfahren soll bei vertretbaren Aufwand für die "Verteidiger" die Datenmenge, welche ein "Angreifer" speichern und verarbeiten müsste, schlicht ganz gewaltig aufblähen.

Das Verfahren soll also nur den Aufwand dafür so weit nach oben treiben, dass dieses (wie es auch in der Kryptographie stets gilt: derzeit) nicht in vernünftiger Zeit möglich ist. Vermutlich dürften die Mängel von rand() oder mt_rand() nicht merklich greifen, weil einfach die Zahl der zu hashenden Passwörter zu gering ist.

Jörg Reinholz