A04 - Cryptographic Failures
als Präsentation ▻Auf Platz 4 der OWASP Top 10 2025: Cryptographic Failures.
Fehler bei der Verschlüsselung oder fehlende Verschlüsselung kann dazu führen, dass sensible Daten zugänglich werden.
▻Maßnahmen
- Klassifizierung der Daten die verarbeitet, gespeichert oder übertragen werden. Welche Daten sind aufgrund von Datenschutzgesetzen, behördlichen Vorschriften oder Geschäftsanforderungen sensibel?
- Sicherstellen, dass vertrauliche Daten bei der Übertragung („in transit“) und Speicherung („at rest“) durch geeignete Verschlüsselung geschützt werden.
- Kein unnötiges Speichern vertraulicher Daten. Löschung nicht mehr benötigter Daten. Daten, die es nicht gibt, können auch nicht gestohlen werden.
- Sicherstellen, dass starke Algorithmen und Schlüssel verwendet werden.
- Sicherstellen, dass Passwörter mit einem speziell für Passwortschutz entwickelten Algorithmus gespeichert werden.
Starke Algorithmen?
Was passiert, wenn ich das nicht tue, sondern einen veralteten Algorithmus verwende?
▻sha1 ist ein schwacher Algorithmus
Ein Beispiel aus einem Projekt: hier wurde der Algorithmus sha1
verwendet um das Passwort zu verschleiern. Wenn sich jemand
versucht einzuloggen wird das so geprüft:
$passwordhashed = sha1($password);
$stmt = $db->prepare('SELECT * FROM `users` WHERE username = ? AND password = ?');
$stmt->execute(array($username, $passwordhashed));
In der Datenbank sehen die Daten so aus:
INSERT INTO `users` (`id`, `username`, `password`) VALUES
(1, 'student', '08df1a7479ca768d03481fb6534ebe844cc2a2d5'),
(2, 'admin', 'dd94709528bb1c83d08f3088d4043f4742891f4f');
Das sieht ja erst mal gut aus: falls diese Datenbank in falsche Hände gerät sind die Passwörter nicht direkt lesbar.
▻Suche nach dem gehashten Passwort
Nimmt man die gehashte Passwort-Zeichenkette des Admin-Users und googelt danach, findet man direkt diese Seite:


Mehr zum Speichern von Passwörtern im OWASP Password Storage Cheat Sheet
▻Beispiel Passwort Hash
Auch wenn man noch nichts über Kryptographie weiß, kann man mit dem Befehl
password_hash in PHP garantiert einen guten Algorithmus verwenden. Als erstes Argument
pbergibt man das Passwort, als zweites Argument den Namen des Algorithmus:
php
password_hash("asecret", PASSWORD_ARGON2I);
Der Rückgabewert ist ein String aus mehreren Teilen:
$argon2i$v=19$m=65536,t=4,p=1$M3JZTjdOclg3MHRWZ0FSWA$1LPV3a8PHAuERq4JmwU8U0+/IfdkoR/LwfgI/PMuCUk
Salt
Wenn man die Funktion mehrmals aufruft erhält man jedes Mal einen anderen Rückgabewert:
echo password_hash("asecret", PASSWORD_ARGON2I);
echo password_hash("asecret", PASSWORD_ARGON2I);
echo password_hash("asecret", PASSWORD_ARGON2I);
Beispiel-Output:
$argon2i$v=19$m=65536,t=4,p=1$Vmo0MVVlWldObVouZ01VNA$owNwQm+Ggyk316rRT1g4tgCh0QGGipdD4ynhZm93eYw
$argon2i$v=19$m=65536,t=4,p=1$MTUvaFVvaGNseGtxenk4Zg$GeVAk7HfgRxxablh4Qg90mFDH+LwKLUPYv30o50XPJ8
$argon2i$v=19$m=65536,t=4,p=1$MWl2ZmFPa3EvUVE0cXJySA$BzgSMLJtD3rLB2j7oX/EL06QZ+saa8yCyA4WuNu9FxI
Den Output kann man entlanger der Dollar-Zeichen zerlegen. Dann sieht man, dass der Algorithmus und die Parameter für alle drei Aufrufe gleich sind:
| Algorithums | Parameter | Parameter | Random Salt | Hashed Value |
| argon2i | v=19 | m=65536,t=4,p=1 | Vmo0MVVlWldObVouZ01VNA |
owNwQm+Ggyk316rRT1g4tgCh0QGGipdD4ynhZm93eYw |
| argon2i | v=19 | m=65536,t=4,p=1 | MTUvaFVvaGNseGtxenk4Zg |
GeVAk7HfgRxxablh4Qg90mFDH+LwKLUPYv30o50XPJ8 |
| argon2i | v=19 | m=65536,t=4,p=1 | MWl2ZmFPa3EvUVE0cXJySA |
BzgSMLJtD3rLB2j7oX/EL06QZ+saa8yCyA4WuNu9FxI |
Der Wert “Random Salt” wird bei jedem Aufruf von password_hash zufällig erzeugt, und mit dem Passwort konkatiniert. Das Ergebnise wird dann mit der Hash-Funktion behandelt.
So ist gewährleistet, dass der Output jedes Mal anders aussieht, und es um ein vielfaches teurer wird eine vollständige Tabelle aller möglichen Passwörter und Hash-Werte zu erzeugen.
▻Passwort verifizieren
function check_login($username, $password) {
global $dbh;
$statement = $dbh->prepare("SELECT * FROM users WHERE username=?");
$ok = $statement->execute([$username]);
if(! $ok) return null;
$user = $statement->fetch(PDO::FETCH_OBJ);
if(! $user) return null;
if (password_verify($password, $user->hashedpassword)) {
return $user;
} else {
return null;
}
}
Beispiel https
Um die HTTP Verbindung zu verschlüsseln brauchen wir das Protokoll TLS und ein Zertifikat.
Wenn man den Webserver installiert und konfiguriert muss man das wissen und richtig machen.