SSL/SSH schützt zwar die gerade auf dem Weg befindlichen Daten vom Client zum Server: SSL/SSH schützt jedoch nicht die dauernd in einer Datenbank gespeicherten Daten. SSL ist ein "auf-der-Leitung" Protokoll.
Hat ein Angreifer direkten Zugriff auf Ihre Datenbank (den Webserver umgehend), können gespeicherte heikle Daten aufgedeckt oder zweckentfremdet werden, außer wenn die Information von der Datenbank selbst geschützt ist. Die Daten zu verschlüsseln ist ein guter Weg, diese Gefahr zu mildern, doch bieten nur wenige Datenbanken diese Art der Verschlüsselung von Daten.
Der einfachste Weg, dieses Problem zu umgehen ist, erst einmal Ihr eigenes Verschlüsselungspaket zu erstellen, und dieses dann in Ihren PHP Skripten zu nutzen. PHP kann Ihnen in diesem Fall mit seinen verschiedenen Erweiterungen helfen, wie z.B. Mcrypt and Mhash, welche eine große Auswahl an Verschlüsselungsalgorhythmen abdecken. Das Skript verschlüsselt die Daten vor dem Speichern, und entschlüsselt diese wieder beim Erhalt. Siehe die Verweise für weitere Beispiele, wie Verschlüsselung arbeitet.
Im Fall von wirklich versteckten Daten, wenn deren unverfälschte Repräsentation nicht nötig ist (z.B. keine Anzeige), ist Hashing ebenfalls überlegenswert. Das bekannte Beispiel für Hashing ist das Speichern des kryptographischen Hashs eines Passwortes in einer Datenbank, anstatt des Passwortes selbst.
In PHP 5.5 oder neuer bieten die Passwort-Funktionen eine bequeme Möglichkeit sensible Daten zu hashen und mit diesen Hashes zu arbeiten. In PHP 5.3.7+ kann die » password_compat-Bibliothek verwendet werden.
password_hash() wird verwendet, um eine gegebene Zeichenkette unter Verwendung des stärksten zurzeit verfügbaren Algorithmus zu hashen, und password_verify() prüft, ob ein gegebenes Passwort mit dem Hash, der in der Datenbank gespeichert ist, übereinstimmt.
Beispiel #1 Hashen eines Passwortfeldes
<?php
// Speichern des Passwort-Hash
$query = sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');",
pg_escape_string($username),
password_hash($password, PASSWORD_DEFAULT));
$result = pg_query($connection, $query);
// Abfragen, ob der User das richtige Passwort übermittelt hat
$query = sprintf("SELECT pwd FROM users WHERE name='%s';",
pg_escape_string($username));
$row = pg_fetch_assoc(pg_query($connection, $query));
if ($row && password_verify($password, $row['pwd'])) {
echo 'Willkommen, ' . htmlspecialchars($username) . '!';
} else {
echo 'Authentifikation für ' . htmlspecialchars($username) . 'fehlgeschlagen.';
}
?>
In älteren PHP-Versionen kann dies unter Verwendung von crypt() erreicht werden.
Beispiel #2 Hashen eines Passworts unter Verwendung von crypt()
<?php
// Speichern des Passwort-Hash
// $random_chars z.B. unter Verwendung von /dev/random abgerufen
$query = sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');",
pg_escape_string($username),
pg_escape_string(crypt($password, '$2a$07$' . $random_chars . '$')));
$result = pg_query($connection, $query);
// Abfragen, ob der User das richtige Passwort übermittelt hat
$query = sprintf("SELECT pwd FROM users WHERE name='%s';",
pg_escape_string($username));
$row = pg_fetch_assoc(pg_query($connection, $query));
if ($row && crypt($password, $row['pwd']) == $row['pwd']) {
echo 'Willkommen, ' . htmlspecialchars($username) . '!';
} else {
echo 'Authentifikation für ' . htmlspecialchars($username) . ' fehlgeschlagen.';
}
?>