Devs: Passwörter richtig speichern

Veröffentlicht am

Viele Entwickler wissen oft nicht wie sie Passwörter richtig speichern sollen. Dabei kommen dann leider oft Eigenimplementierungen heraus, die alles andere als sicher sind. Viele basieren auf dem Geheimhaltungsprinzip, welches schon längst als veraltet gilt. Oder im schlimmsten Fall gar eine Speicherung in Klartext!

Dabei gibt es viele Möglichkeiten, Passwörter sicher zu speichern. Heutzutage gibt es dafür für nahezu jede Sprache passende Implementierungen.

Hierbei gibt es zwei gängige Möglichkeiten Passwörter zu sichern. Die erste Möglichkeit besteht darin die Passwörter mit einem Einweg-Hashalgorithmus zu schützen. Dies kommt allerdings nur in Frage, wenn die Passwörter nicht mehr im Klartext benötigt werden. Dies ist in der Mehrzahl der Anwendungen der Fall. Ansonsten gibt es noch diverse Verschlüsselungsverfahren, bei denen das Passwort mit einem geheimen Schlüssel verschlüsselt wird.

In diesem Artikel werde ich allerdings mehr auf die Hashverfahren eingehen. Diese sind oberflächlich gesehen ersteinmal Algorithmen, die eine relativ schnelle Unkenntlichmachung des Passwortes erlauben. Die Errechnung eines Hashes ohne den Wert zu kennen, sollte dabei sehr schwer möglich, am Besten nur durch Raten möglich sein. Hierbei ist zu beachten, das diese Hashverfahren mit zunehmender Rechenleistung entsprechend unsicher werden. So sollte man regelmäßig prüfen, ob das Hashverfahren noch den aktuellen Standard entspricht.

Hier ist als Beispiel md5 zu nennen, eines der ersten Verfahren. Dieses ist bereits seit Jahren knackbar und sollte für Passwörter auf gar keinen Fall Verwendung finden.

Um die Sicherheit eines Verfahrens noch zu erhöhen, hierbei ist es grundsätzlich egal, um welches es sich handelt, gibt es noch eine Ergänzung. Den sogenannten Salt. Dieser erhöht aber nicht die Sicherheit des Algorithmus an sich. Hierbei sichert man sich gegen sogenannte Hashtabellen oder auch Rainbowtabellen ab.

Hierzu eine kurze Erklärung zur Rainbowtabelle, diese ist eine Zuordnung von Hahes eines gewissen Algorithmus zum Klartextpasswort. Hierzu eine kleine Beispieltabelle anhang des veralteten md5:

Hash Passwort in Klartext
e8636ea013e682faf61f56ce1cb1ab5c geheim
e22a63fb76874c99488435f26b117e37 passwort
97c2186561244f033daec7c483f20df1 md5IsSuppa

Jetzt gehen wir einmal davon aus, ein Hacker erbeutet folgende Datensätze:

Vorname Nachname Hash des Passwort
Max Mustermann e8636ea013e682faf61f56ce1cb1ab5c
Ulrike Rumpelstolz e8636ea013e682faf61f56ce1cb1ab5c

Dies ermöglicht eine leichte Ermittlung der Passwörter der entsprechenden Muster:

So entimmt man den Datensätzen, das Max Mustermann das Passwort geheim vergeben hat, da sein Hash dem aus der Rainbowtabelle mit dem Klartext-Passwort entspricht. So haben wir ohne jeglichen Aufwand das Passwort des Benutzers Max Mustermann, welcher wahrscheinlich überall dieses Passwort verwendet. Durch simples Ausprobieren wird man sicher an den ein oder anderen Account gelangen.

Und das ganze jetzt noch einmal mit Salt:

Vorname Nachname Hash des Passwort Salt
Max Mustermann ab8ad32fcd0121853697e6d66521d98d rbxtJWnKNJ
Ulrike Rumpelstolz 13d0c06961b061ca86d27968e50da9a1 wY0ienc41S

Obwohl es sich bei jedem der Datensätze wieder um das Passwort geheim handelt, ist dieses nicht einfach als dieses Passwort zu erkennen. Das liegt daran, dass nicht nur das Passwort gehasht wird sondern eine Kombination aus Passwort und Salt. So z. B. für Max Mustermann geheimrbxtJWnKNJ, das erzeugt eine größere Vielfalt an Möglichkeiten für das Passwort. Hierbei ist jediglich wichtig, das der Salt ein einzigartiger String ist, so dass keine Rainbowtabelle angewendet werden kann. Dieser kann ohne Probleme im zugehörigen Datensatz im Klartext gespeichert werden und kann so bei der Passwortprüfung Verwendung finden.

Als Beispiel für einen solchen Hashalgorithmus möchte ich an dieser Stelle bcrypt empfehlen. Bei diesem kannn man die Anzahl der Durchgänge einstellen, welche je nach Anwendungsfall entsprechend hoch eingestellt werden können, je höher der übergebene Kostenfaktor, desto höher die Sicherheit. Zusammen mit einem Hash bietet das eine einfache und sichere Möglichkeit Passwörter mit zeigemäßem Schutz zu speichern.

Hier das ganze einmal exemplarisch in PHP:

$password = "h4shenGehtGanz3inf4ch";
$salt = uniqid(); // Unique Id liefert einen String basierend auf dem Unix-Timestamp zurück

// Erzeugung eines Hash anhand des Salt und Passwort mit bcrypt durch PHPs password_hash Funktion, der Salt kann hierbei auch durch PHP verwaltet werden.
$hash = password_hash($password . $salt, PASSWORD_BCRYPT,["cost" => 12]);

Die genaue Funktionsweise der Hashes usw. für Interessierte findet sich u. a. bei Wikipedia und Co. oder in entsprechenden Publikationen. Für die meisten Entwickler reicht es allerdings zu wissen, ob der verwendete Algorithmus noch als sicher gilt oder nicht.

In dem Sinne sollten wir uns unserer Verantwortung gegenüberden Nutzern bewusst werden und anfangen die Welt ein bisschen sicherer zu machen! :)