vorige Präsentation: A03 - Software Supply Chain Failures | zurück zum Buch-Kapitel [esc] | Nächste Präsentation A05 - Injection
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.
Was passiert, wenn ich das nicht tue, sondern einen veralteten Algorithmus verwende?
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.
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
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
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.
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;
}
}
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.
vorige Präsentation: A03 - Software Supply Chain Failures | zurück zum Buch-Kapitel [esc] | Nächste Präsentation A05 - Injection
/
#