Passwort-Hashing: Sichere Speicherung | Enjyn Gruppe
Hallo Welt
Hallo Welt
Original Lingva Deutsch
Übersetzung wird vorbereitet...
Dieser Vorgang kann bis zu 60 Sekunden dauern.
Diese Seite wird erstmalig übersetzt und dann für alle Besucher gespeichert.
0%
DE Zurück zu Deutsch
Übersetzung durch Lingva Translate

241 Dokumentationen verfügbar

Wissensdatenbank

Passwort Hashing Sicher

Zuletzt aktualisiert: 20.01.2026 um 10:05 Uhr

Passwort-Hashing: Sichere Speicherung

Passwörter dürfen NIEMALS im Klartext gespeichert werden. Dieser Guide erklärt, wie Sie Passwörter sicher hashen und welche Algorithmen Sie verwenden sollten.

Warum Hashing?

Bei einem Datenleck sind gehashte Passwörter nutzlos für Angreifer – sie können nicht zurückgerechnet werden.

Klartext:     "geheim123"
MD5 (unsicher): e99a18c428cb38d5f260853678922e03
bcrypt (sicher): $2y$10$X4kv7j5ZcQdx8.9sFqK...

Sichere Algorithmen

Algorithmus Empfehlung Anmerkung
Argon2id ⭐⭐⭐ Beste Wahl Gewinner PHC, memory-hard
bcrypt ⭐⭐⭐ Sehr gut Bewährt, weit verbreitet
scrypt ⭐⭐ Gut Memory-hard
PBKDF2 ⭐ Akzeptabel Wenn nichts anderes verfügbar
❌ NIEMALS verwenden:
  • MD5: Zu schnell, Kollisionen
  • SHA1: Zu schnell, gebrochen
  • SHA256 ohne Salt/Iteration: Rainbow Tables
  • Eigene Algorithmen: Nicht getestet

PHP: password_hash()

<?php
// ✅ EMPFOHLEN: bcrypt (Standard)
$hash = password_hash($password, PASSWORD_DEFAULT);

// Argon2id (PHP 7.3+)
$hash = password_hash($password, PASSWORD_ARGON2ID);

// Mit Optionen
$hash = password_hash($password, PASSWORD_BCRYPT, [
    'cost' => 12  // Standard: 10
]);

$hash = password_hash($password, PASSWORD_ARGON2ID, [
    'memory_cost' => 65536,  // 64 MB
    'time_cost' => 4,
    'threads' => 3
]);

Passwort verifizieren

<?php
// Passwort prüfen
if (password_verify($inputPassword, $storedHash)) {
    echo "Passwort korrekt!";

    // Rehash wenn nötig (nach Algorithmus-Update)
    if (password_needs_rehash($storedHash, PASSWORD_DEFAULT)) {
        $newHash = password_hash($inputPassword, PASSWORD_DEFAULT);
        // In Datenbank speichern
    }
} else {
    echo "Passwort falsch!";
}

Node.js: bcrypt

const bcrypt = require('bcrypt');

// Passwort hashen
const saltRounds = 12;
const hash = await bcrypt.hash(password, saltRounds);

// Passwort verifizieren
const isMatch = await bcrypt.compare(inputPassword, storedHash);

if (isMatch) {
    console.log('Passwort korrekt!');
}

Mit Argon2

const argon2 = require('argon2');

// Hashen
const hash = await argon2.hash(password, {
    type: argon2.argon2id,
    memoryCost: 65536,
    timeCost: 3,
    parallelism: 4
});

// Verifizieren
const isValid = await argon2.verify(storedHash, inputPassword);

Python: passlib oder bcrypt

# Mit passlib (empfohlen)
from passlib.hash import argon2

# Hashen
hash = argon2.hash(password)

# Verifizieren
if argon2.verify(input_password, stored_hash):
    print("Passwort korrekt!")

# Mit bcrypt
import bcrypt

# Hashen
salt = bcrypt.gensalt(rounds=12)
hash = bcrypt.hashpw(password.encode(), salt)

# Verifizieren
if bcrypt.checkpw(input_password.encode(), stored_hash):
    print("Passwort korrekt!")

Wie funktioniert bcrypt?

$2y$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW
└─┬┘└┬┘└────────────────────┬────────────────────┘└──────────┬──────────┘
  │  │                     Salt (22 Zeichen)              Hash (31 Zeichen)
  │  └── Cost Factor (2^12 = 4096 Iterationen)
  └── Algorithmus Version (2y = bcrypt)
  • Salt: Zufällig, automatisch generiert, im Hash enthalten
  • Cost Factor: Exponentiell mehr Rechenzeit
  • Result: 60 Zeichen String

Cost Factor / Work Factor

Cost Iterationen Zeit (ca.)
10 1.024 ~100ms
12 4.096 ~300ms
14 16.384 ~1s

Ziel: 250-500ms pro Hash. Zu schnell = unsicher, zu langsam = schlechte UX.

Migration von MD5/SHA

<?php
// Bei Login alte Hashes migrieren
function loginUser($username, $password) {
    $user = getUserFromDb($username);

    // Alter MD5-Hash?
    if (strlen($user['password_hash']) === 32) {
        if (md5($password) === $user['password_hash']) {
            // Neu hashen und speichern!
            $newHash = password_hash($password, PASSWORD_DEFAULT);
            updateUserPassword($user['id'], $newHash);
            return true;
        }
    }

    // Neuer bcrypt-Hash
    return password_verify($password, $user['password_hash']);
}

Best Practices

💡 Empfehlungen:
  • Argon2id oder bcrypt verwenden
  • Eingebaute Funktionen nutzen (nicht selbst implementieren)
  • Cost Factor regelmäßig erhöhen
  • password_needs_rehash() nutzen
  • Passwort-Länge auf 72 Bytes begrenzen (bcrypt-Limit)
  • Pepper optional (zusätzlicher Secret Key)

Weitere Informationen

Enjix Beta

Enjyn AI Agent

Hallo 👋 Ich bin Enjix — wie kann ich dir helfen?
120