Wieso werden in WordPress Passwörter gehasht?

Mir ist bei einem Blick in die Datenbank aufgefallen, dass WordPress Passwörter nicht im Klartext, sondern als Hashwert abspeichert. Wieso wird das so gemacht? Außerdem sieht der Hashwert anders aus, als das was mein Computer mit md5sum ausgibt. Warum ist das so?

Da die Frage vielleicht auch noch andere interessiert, antworte ich etwas ausführlicher:

Warum werden Passwörter überhaupt gehasht?

Wenn die Passwörter im Klartext gespeichert würden, könnte jeder mit Zugriff auf die Datenbank oder Administratoren-Rechten die Passwörter auslesen. Da es immer noch Nutzer geben soll, die das selbe Passwort für verschiedene Dienste vom Online-Buchhändler bis zur Flugbuchung verwenden, wäre ein Missbrauch möglich. Umgekehrt könnte bei einem Angriff den Administratoren unterstellt werden, sie hätten damit zu tun, weil das Passwort in der WordPress-Installation verwendet wurde.

Was bedeutet überhaupt Hash?

Ein Hash ist ein durch Verschlüsselung erzeugter Wert, der aus der Eingabe von Klartext erzeugt wird, aber keine Rückschlüsse auf den Klartext erlaubt. Durch die Verwendung von Hash-Zeichenketten besteht nicht mehr die Gefahr, dass ein Passwort missbraucht werden kann, weil das Passwort nicht aus dem Hashwert abgeleitet werden kann.

Was nützt der Hashwert, wenn er keinen Rückschluss auf das Passwort erlaubt?

Bei einer erneuten Eingabe des Passworts (z.B. im Anmeldeformular) kann aus dieser Eingabe sofort ein neuer Hash-Wert errechnet werden. Dieser Hashwerte wird dann mit dem gespeicherten Hash-Wert verglichen. Durch den Abgleich der beiden Hashwerte wird eine Authentifizierung ermöglicht.

Prima. Dann nutzen wir also MD5-Hashwerte?

Grundsätzlich eine gute Idee, aber für häufig vorkommende Zeichenketten („Rolling Stones, badekappe“) könnte jemand Hashwerte berechnen lassen und in einer so genannten Rainbow Table speichern. Diese Tabelle kann anschließend mit in der Datenbank gespeicherten Hash-Werten abgeglichen werden (genauso, wie es ja bei der Anmeldung passiert), um so Rückschlüssel auf das Passwort im Klartext zu ziehen. Da sich nicht jeder Nutzer an die Empfehlung hält, ausreichend komplexe Passwörter zu verwenden, ist die Trefferquote entsprechend hoch.

Eine Rainbow Table mag vielleicht einen Hash-Wert für „Rolling Stones“ beinhalten, aber nicht für „Rolling Stones #4%3hZo/?23“. Der Trick, über eine Rainbow Table Passwörter auszulesen, kann also verhindert werden, wenn jedem Passwort eine für die WordPress-Installation individuelle Zeichenkette angehängt wird.
WordPress erzeugt dazu bei der Installation so genannte SALT-Schlüssel, die in der wp-config.php abgelegt werden. Gibt ein Benutzer ein neues Passwort ein, wird das Passwort zusammen mit dem für diese WordPress-Installation einzigartigen SALT-Schlüssel gehasht. Im Gegensatz zu einfachen, mit dem Algorithmus MD5 errechneten Hashwerten wird dem mit dem Portable PHP password hashing framework so verschlüsselten Passwort eine Kennung für die Methode und der SALT-Key angehängt: $METHODE$SALT$PASSWORTHASH – das ist das, was du als $P$B gesehen hast.

Was mache ich, wenn ich mein Passwort vergessen habe und das Passwort in der Datenbank ändern möchte?

Dazu kannst du aus deinem Passwort mit einem Online-Dienst oder über das Terminal (echo -n Passwort | md5sum) einen MD5-Hash-Wert errechnen lassen und diesen als Passwort angeben.
Alternativ bietet dir das zur Datenbankverwaltung oft genutzte phpMyAdmin die Möglichkeit, ein im Klartext eingegebenes Passwort mit MD5 zu verschlüsseln. Dazu musst du im Pulldown-Menü der Spalte „Funktion“ MD5 auswählen (Pfeil):

phpMyAdmin mit Spalte Funktion zur Auswahl des MD5-Algorithmus
phpMyAdmin bietet eine Möglichkeit, den Hashwert direkt beim Einfügen des Passworts zu berechnen

Aber nun ist das Passwort ja wieder in MD5! Was ist jetzt mit diesen Rainbaow-Tables?

Beim nächsten Anmeldevorgang hat der in der Datenbank gespeicherte Hashwert keine Vorsilbe für die Verschlüsselungsmethode und den SALT-Key, es wird also nur der MD5-Hashwert abgeglichen. WordPress erkennt dabei, dass es sich um einen einfachen MD5-Hashwert handelt und ersetzt den Datenbankeintrag wieder mit einem Hashwert mit SALT. Eine „Gefahr“, dass der Hashwert von jemandem (mit Zugriff auf die Datenbank!) ausgelesen und mit Rainbow-Tabellen abgeglichen werden kann, besteht also nur für die kurze Zeit zwischen Eingabe des MD5-Hashwerts in der Datenbank und einer erneuten Anmeldung im WordPress-Backend.

Ich habe aber gelesen, MD5 soll unsicher sein?

Durch die Verwendung des SALT-Keys entfällt zumindest die Gefahr, dass Passwörter über Rainbow-Tables ermittelt werden. MD5 gilt aber inzwischen als Algorithmus nicht mehr sicher und es wird empfohlen, auf sicherere Algortihmen umzusteigen. Wenn jemand erst einmal Zugriff auf die Datenbank hat (und damit in der WordPress-Installation bereits beträchtlichen Schaden anrichten kann), sind auch die Passwörter begrenzt sicher, wie dieser Beitrag beschreibt: https://frenxi.com/cracking-wordpress-password-hash/.

Du findest im Plugin-Verzeichnis Plugins, die statt MD5 dass sicherere BCrypt verwenden. Es wurde schon mehrfach vorgeschlagen, im WordPress-Core auf eine Verschlüsselung mit BCrypt umzusteigen, das aber nicht von jedem Webserver unterstützt wird. Deshalb die Plugin-Lösung. Bug-Tickets zum Thema Verwendung von MD5 liegen vor.

Wer nochmal zum Thema Passwort-Hashwerte nachlesen mag: https://developer.wordpress.org/reference/functions/wp_hash_password/