MB Dev .tech
Registrieren Login

Sicherheit Basics · Passwörter & Hashing

← Zurück zu Sicherheit Basics

Passwörter gehören zu den sensibelsten Daten in einer Anwendung. Wenn du hier Fehler machst, betrifft das nicht nur „dein Projekt“, sondern im schlimmsten Fall echte Menschen und deren Accounts.

Achtung
Passwörter niemals im Klartext speichern

Weder in der Datenbank, noch in Logs, noch irgendwo „zur Sicherheit“. Stattdessen nutzt man Hashing.

1) Was ist Hashing?

Ein Hash ist eine Art „Fingerabdruck“ eines Textes. Aus einem Passwort wird ein scheinbar zufälliger String erzeugt. Wichtig: Ein guter Hash ist nicht einfach rückwärts zu berechnen.

Das ist der Trick bei Passwörtern: Du speicherst nur den Hash, und beim Login prüfst du, ob das eingegebene Passwort zum gespeicherten Hash passt.

Merke
Du „vergleichst“, du „entschlüsselst“ nicht

Gute Passwort-Hashes werden nicht entschlüsselt. Man prüft nur: „Passt dieses Passwort zu diesem Hash?“

2) Hashing vs. Verschlüsselung (wichtiger Unterschied)

Diese Begriffe werden oft verwechselt:

  • Verschlüsselung: kann wieder entschlüsselt werden (mit Key).
  • Hashing: ist „one-way“ (nicht sinnvoll rückwärts).
Tipp
Passwort = Hashing

Alles, was du später wieder „im Klartext“ brauchst (z.B. API-Token, geheime Notizen), kann Verschlüsselung sein. Passwörter: Hashing.

3) Passwörter in PHP richtig hashen

In PHP nutzt du dafür password_hash(). Das erzeugt automatisch einen sicheren Hash inklusive Salt. Du musst also nicht „selbst Salts bauen“.

Registrierung: Hash erzeugen

$passwordPlain = "EinSicheresPasswort!";

$hash = password_hash($passwordPlain, PASSWORD_DEFAULT);

// In die Datenbank kommt nur $hash (nicht das Klartext-Passwort)
Merke
PASSWORD_DEFAULT ist sinnvoll

PHP kann den Standard-Algorithmus im Laufe der Zeit verbessern. Dein Code bleibt dadurch zukunftssicherer.

4) Passwort prüfen beim Login

Beim Login hast du: das eingegebene Passwort (Klartext) und den gespeicherten Hash (aus der DB). Du prüfst das mit password_verify().

Login: Passwort prüfen

$inputPassword = "EinSicheresPasswort!";
$storedHash    = '$2y$10$...'; // kommt aus der Datenbank

if (password_verify($inputPassword, $storedHash)) {
    echo "Login ok";
} else {
    echo "Login fehlgeschlagen";
}
Achtung
Nie Hashes „selbst vergleichen“

Nicht: hash($algo, $pw) === $storedHash. Passwörter brauchen spezielle, langsame Algorithmen und eine sichere Implementierung. Dafür sind password_hash und password_verify da.

5) Rehashing: Hashes später verbessern

Manchmal verbessert PHP die empfohlenen Einstellungen (z.B. Cost/Algorithmus). Dann möchtest du bestehende Hashes nach und nach „modernisieren“. Das geht beim Login mit password_needs_rehash().

Rehash beim Login (Prinzip)

if (password_verify($inputPassword, $storedHash)) {

    if (password_needs_rehash($storedHash, PASSWORD_DEFAULT)) {
        $newHash = password_hash($inputPassword, PASSWORD_DEFAULT);

        // $newHash in der DB speichern
    }

    echo "Login ok";
}
Tipp
Rehash ist ein „leises Upgrade“

Du musst keine „alle Nutzer zurücksetzen“-Aktion starten. Du verbesserst Hashes automatisch, wenn sich jemand einloggt.

6) Typische Fehler bei Passwörtern

  • Klartext speichern (fatal)
  • MD5/SHA1/SHA256 verwenden (für Passwörter ungeeignet, zu schnell)
  • Passwörter loggen (z.B. bei Debug-Ausgaben)
  • Fehlermeldungen zu genau machen („E-Mail existiert, Passwort falsch“)
Achtung
MD5/SHA sind nicht „automatisch unsicher“ – aber fürs Passwort falsch

Hash-Funktionen wie SHA256 sind super für Checksummen. Aber für Passwörter willst du absichtlich „langsam“ sein, damit Brute-Force-Angriffe teuer werden.

Kleine Aufgaben (zum Mitdenken)

Aufgabe 1: Was speichert man in der DB?

Speichert man beim Registrieren das Klartext-Passwort oder den Hash? Und warum?

Lösung einblenden
Lösung
Man speichert nur den Hash

Der Hash reicht, um beim Login zu prüfen, ob das Passwort stimmt. Wenn die DB kompromittiert wird, sind Klartext-Passwörter sofort missbrauchbar. Hashes sind deutlich besser geschützt (auch wenn man trotzdem gut absichern muss).