Wieso man MD5/SHA1 nicht für das Speichern von Passwörtern verwenden sollte
Leider findet man heutzutage immer noch viele Webseiten und auch Software, die Passwörter ihrer Nutzer ganz schlicht und einfach mit MD5 oder SHA1 gehasht speichern. Aus Aspekten der Sicherheit dies ist aber nicht die ideale Variante.
Der Grund dafür ist eigentlich schlicht und einfach die Geschwindigkeit dieser Hash-Funktionen. So schauen wir uns doch einfach mal an, wie lange zum Beispiel mein Laptop, der höchstens Mittelfeld ist, was die Leistung angeht, für jeweils 1 Millionen Hashes mit MD5 und mit SHA1 braucht:
MD5 0,67 Sekunden
SHA1 0,83 Sekunden
Wie man sieht, braucht mein Laptop nicht einmal 1 Sekunden, um 1 Millionen Hashs mit MD5 und SHA1 zu berechnen. Das bedeutet zeitgleich, dass ich als Hacker mit meinem Laptop bereits pro Sekunde über 1 Millionen mögliche Passwörter durchprobieren könnte, um das jeweilige Passwort im Klartext zu dem jeweiligen Hash zu finden. Nutzt man dann noch spezielle Crack-Software, die auch statt der CPU des Computers auch die GPU der Grafikkarte verwenden kann, die in solchen Berechnungen noch einmal deutlich schneller ist, anstelle wie ich für mein Beispiel ein einfaches PHP-Skript, so kann man mit einem einfachen PC und einer guten Grafikkarte auch schnell rund 8,5 Milliarden MD5-Hashs oder 3 Milliarden SHA1-Hashs pro Sekunde berechnen.
Diese hohe Geschwindigkeit wird dann zu einem Problem, wenn ein Angreifer eure Datenbank auslesen kann und so an die Hash-Werte der Passwörter eurer Nutzer kommt. Viele Personen benutzen leider unsichere Passwörter mit zu wenig Zeichen. Der Angreifer kann dann pro Sekunde 8,5 Milliarden Passwörter durchprobieren und findet recht schnell die Passwörter eurer Benutzer heraus heraus. Zum Durchprobieren aller 6-stelligen Passwörter die nur aus Kleinbuchstaben und Zahlen bestehen benötigt der Angreifer nur rund 0,25 Sekunden und für Passwörter mit 8 Stellen weniger als 6 Minuten.
Doch was sollte man dann verwenden, wenn nicht MD5/SHA1?
Um das Problem zu beheben dass MD5 und SHA1 zu schnell ist, sollte eine Hashfunktion verwendet werden die Rechenintensiver ist. Könnte ein Angreifer statt 8,5 Milliard Passwörter pro Sekunde nur 1 Million Passwörter pro Sekunde testen, so würde sein Angriff auf 8 stellige Passwörter rund 800 Stunden dauern.
Eine solch langsame Hashfunktion und damit für Passwörter gut geeignete wäre zum Beispiel Bcrypt, die man seit PHP 5.3.7 besonders einfach verwenden kann, wie bereits in Passwörter sicher speichern genauer klärt wird. Möchte man Passwörter wirklich sicher speichern, so sollte man sich diesen Text Passwörter sicher speichern unbedingt durchlesen und entsprechend anwenden, da auch wichtige Mechanismen wie z.B. der Einsatz eines für jeden Hash zufälligen Salts automatisch im Hintergrund umgesetzt werden, welches die Sicherheit der gespeicherten Passwörter deutlich erhöht. Zusätzlich ist es sehr einfach möglich, gewisse Parameter nachträglich anzupassen, um die Passwörter der Nutzer auch bei immer besser werdender Hardware weiterhin sicher zu speichern, ohne alle Nutzer ihr Passwort ändern zu lassen oder die Passwörter aller Nutzer zurücksetzen zu müssen.
Unabhängig von den ganzen fortgeschrittenen Mechanismen, die im Hintergrund von diesen Funktionen für einen übernommen werden, welche
die Sicherheit der gespeicherten Passwörter noch zusätzlich deutlich erhöht, dauert das berechnen eines Hashs mit dieser Funktion deutlich länger.
Hier der direkte Vergleich:
MD5 0,67 Sekunden
SHA1 0,83 Sekunden
password_hash ~27 Stunden (~99300 Sekunden)
(hochgerechnet anhand der Dauer für 10.000 Hashes mit 993 Sekunden)
Auch wenn die Zeiten je nach Hardware deutlich variieren können, sieht man jedoch im direkten Vergleich, dass MD5 und SHA1 in derselben Zeit deutlich mehr Versuche erlaubt zu einem Hash das dazugehörende Passwort zu finden, als bei der einfache Verwendung von password_hash.
Aber muss der Nutzer dann nicht viel zu lange warte, um sich z.B. einzuloggen?
Da zum Beispiel beim Einloggen oder Erstellen eines Nutzers in der Regeln nur ein Hash berechnet werden muss und dies auch mit der password_hash Funktion gerade mal ~0,08 Sekunden dauert (exakte Dauer variiert je nach Hardware, jedoch ist erkennbar, dass diese Zeit nicht wirklich für den Nutzer spürbar ist), wird es dem einzelnen Nutzer nicht auffallen, dass diese Funktion deutlich langsamer ist, jedoch braucht ein Hacker deutlich mehr Zeit und/oder Rechenleistung, um das benutzte Passwort zu dem jeweiligen Hash zu finden.
Steht einem wirklich kein PHP 5.3.7 oder höher zur Verfügung, sollte man auf die crypt-Funktion in Verbindung mit Blowfish zurückgreifen. Da dieser Umgang mit der crypt-Funktion bei weitem nicht so einfach ist, wie die in Passwörter sicher speichern vorgestellten Funktionen, sollte man die crypt-Funktion nur verwenden, wenn einem kein PHP in Version 5.3.7 oder höher zur Verfügung steht.
Autor: Tim Pangritz