> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Hashing

> Erläutert, wie Sie mit der Hash-Facade von Laravel Passwörter sicher hashen und prüfen. Beschreibt die Konfiguration und Nutzung der Algorithmen bcrypt und Argon2.

## Was ist Hashing?

Beim Hashing werden Klartextdaten wie ein Passwort per Einwegtransformation in einen String fester Länge überführt.
Aus dem gleichen Input entsteht immer der gleiche Hash-Wert, aber der Klartext lässt sich aus dem Hash nicht wiederherstellen.

Die Facade `Hash` von Laravel unterstützt zur sicheren Ablage von Passwörtern die Algorithmen **bcrypt** und **Argon2**.

### Vergleich der Algorithmen

| Algorithmus  | Eigenschaften                                                                   | Empfehlung                                         |
| ------------ | ------------------------------------------------------------------------------- | -------------------------------------------------- |
| **bcrypt**   | Rechenaufwand über den Arbeitsfaktor (Rounds) einstellbar. Standard.            | Übliche Webanwendungen                             |
| **argon2i**  | Speicher, Zeit und Thread-Anzahl einstellbar. Robust gegen Seitenkanalangriffe. | Anwendungsfälle mit hohen Sicherheitsanforderungen |
| **argon2id** | Hybrid aus argon2i und argon2d. Von der PHC empfohlen.                          | Bei neuen Projekten mit Argon2                     |

<Info>
  Der Arbeitsfaktor (Work Factor) von bcrypt steuert, wie lange die Hash-Berechnung dauert. Je langsamer der Hash, desto resistenter ist das System gegen Brute-Force-Angriffe. Wenn Hardware schneller wird, sollten Sie den Arbeitsfaktor erhöhen, um das Sicherheitsniveau zu halten.
</Info>

### Ablauf von Hashing und Prüfung

```mermaid theme={null}
flowchart LR
    A[Klartext-Passwort] -->|Hash::make| B["Hash-Wert<br>in DB gespeichert"]
    C[Eingabe beim Login] -->|Hash::check| D{Übereinstimmung?}
    B --> D
    D -->|true| E[Login erfolgreich]
    D -->|false| F[Login fehlgeschlagen]
```

***

## Konfiguration

Standardmäßig verwendet Laravel den Treiber `bcrypt`. Über die Umgebungsvariable `HASH_DRIVER` können Sie ihn ändern.

```ini theme={null}
# .env
HASH_DRIVER=bcrypt  # bcrypt / argon / argon2id
```

Um die Hashing-Konfiguration anzupassen, veröffentlichen Sie die Konfigurationsdatei mit `config:publish`.

```shell theme={null}
php artisan config:publish hashing
```

Danach lassen sich in `config/hashing.php` etwa Standard-Arbeitsfaktoren anpassen.

***

## Grundlegende Verwendung

### Passwort hashen

Übergeben Sie `Hash::make()` das Klartext-Passwort, um den Hash zu erhalten. Speichern Sie diesen Hash in der Datenbank.

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class PasswordController extends Controller
{
    public function update(Request $request): RedirectResponse
    {
        $request->validate([
            'password' => ['required', 'min:8', 'confirmed'],
        ]);

        $request->user()->fill([
            'password' => Hash::make($request->password),
        ])->save();

        return redirect('/profile');
    }
}
```

<Warning>
  Speichern Sie nur den Hash-Wert in der Datenbank – niemals das Klartext-Passwort.
</Warning>

### Arbeitsfaktor von bcrypt anpassen

Über die Option `rounds` regeln Sie den Rechenaufwand des Hashings. Höhere Werte sind sicherer, benötigen aber mehr Zeit.
Der Standard (12) ist für die meisten Anwendungen angemessen.

```php theme={null}
$hashed = Hash::make('plain-text-password', [
    'rounds' => 14,
]);
```

### Arbeitsfaktor von Argon2 anpassen

Bei Argon2 passen Sie den Rechenaufwand über die Optionen `memory`, `time` und `threads` an.

```php theme={null}
$hashed = Hash::make('plain-text-password', [
    'memory'  => 65536, // in KiB
    'time'    => 4,
    'threads' => 2,
]);
```

| Option    | Beschreibung              | Standardwert |
| --------- | ------------------------- | ------------ |
| `memory`  | Genutzter Speicher in KiB | 65536        |
| `time`    | Anzahl der Iterationen    | 4            |
| `threads` | Anzahl der Threads        | 1            |

<Tip>
  Details zu den Argon2-Optionen finden Sie in der [PHP-Dokumentation](https://secure.php.net/manual/de/function.password-hash.php).
</Tip>

***

## Passwörter prüfen

Mit `Hash::check()` prüfen Sie, ob ein Klartext-Passwort dem gespeicherten Hash entspricht.
Ein typisches Einsatzgebiet ist die Login-Logik.

```php theme={null}
use Illuminate\Support\Facades\Hash;

if (Hash::check($request->password, $user->password)) {
    // Passwörter stimmen überein
} else {
    // Passwörter stimmen nicht überein
}
```

Verwenden Sie `Auth::attempt()`, wird diese Prüfung automatisch durchgeführt – ein direkter Aufruf ist dann nicht nötig.
`Hash::check()` ist praktisch, wenn Sie das aktuelle Passwort manuell verifizieren möchten.

```php theme={null}
// Aktuelles Passwort im Passwort-Änderungsformular prüfen
if (! Hash::check($request->current_password, $request->user()->password)) {
    return back()->withErrors(['current_password' => 'Das aktuelle Passwort ist nicht korrekt.']);
}
```

***

## Neubestimmung des Hashes

Mit `Hash::needsRehash()` prüfen Sie, ob ein bestehender Hash mit einem anderen Arbeitsfaktor erzeugt wurde als aktuell konfiguriert.
Nützlich, um nach einer Änderung des Arbeitsfaktors bestehende Hashes auf die neue Konfiguration umzustellen.

```php theme={null}
use Illuminate\Support\Facades\Hash;

if (Hash::needsRehash($user->password)) {
    $user->update([
        'password' => Hash::make($plainTextPassword),
    ]);
}
```

Ein Beispiel für Rehash bei erfolgreichem Login:

```mermaid theme={null}
flowchart TD
    A[Login erfolgreich] --> B{needsRehash?}
    B -->|true| C[Mit neuem Arbeitsfaktor<br>neu hashen und speichern]
    B -->|false| D[Weiter wie gewohnt]
    C --> D
```

```php theme={null}
// Beim Login neu hashen
if (Auth::attempt($credentials)) {
    if (Hash::needsRehash(Auth::user()->password)) {
        Auth::user()->update([
            'password' => Hash::make($credentials['password']),
        ]);
    }

    return redirect()->intended('/dashboard');
}
```

<Tip>
  Passen Sie den Arbeitsfaktor bei Hardware-Fortschritten regelmäßig an, um Ihr Sicherheitsniveau zu erhalten. Mit `needsRehash()` können Sie beim natürlichen Login die Passwörter im Vorbeigehen aktualisieren.
</Tip>

***

## Algorithmusverifikation

Standardmäßig prüft `Hash::check()`, ob der Hash mit dem aktuell konfigurierten Algorithmus erzeugt wurde.
Bei einem abweichenden Algorithmus wird eine `RuntimeException` ausgelöst.

Damit lassen sich Angriffe durch das Vertauschen des Hash-Algorithmus verhindern.

Wenn Sie – etwa während einer Migration – mehrere Algorithmen gleichzeitig unterstützen müssen, können Sie diese Prüfung mit `HASH_VERIFY=false` deaktivieren.

```ini theme={null}
# .env
HASH_VERIFY=false
```

<Warning>
  Mit `HASH_VERIFY=false` schalten Sie die Algorithmusprüfung ab. Nutzen Sie das nur während einer Migration und setzen Sie den Wert danach auf `true` (Standard) zurück.
</Warning>

***

## Zusammenfassung

| Aufgabe                         | Vorgehen                        |
| ------------------------------- | ------------------------------- |
| Passwort hashen                 | `Hash::make($password)`         |
| Hash prüfen                     | `Hash::check($plain, $hash)`    |
| Rehash-Bedarf prüfen            | `Hash::needsRehash($hash)`      |
| Hashing-Treiber wechseln        | Umgebungsvariable `HASH_DRIVER` |
| Algorithmusprüfung deaktivieren | `HASH_VERIFY=false`             |

## Nächste Schritte

<Card title="Einführung in die Authentifizierung" icon="lock" href="/de/authentication">
  Verstehen Sie den gesamten Ablauf der Authentifizierung, inklusive des Logins mit `Hash::check()`.
</Card>


## Related topics

- [Verschlüsselung (Encryption)](/de/encryption.md)
- [Laravel Fortify und Starter-Kits](/de/advanced/fortify.md)
- [Eigene Casts in Eloquent](/de/advanced/eloquent-casts.md)
- [Deployment](/de/deployment.md)
- [Upgrade von Laravel 10 auf 11](/de/blog/upgrade-10-to-11.md)
