Php Hashen mit "Salz" / PASSWORD_DEFAULT?
$password = "passwort";
$hashed = password_hash($password, PASSWORD_DEFAULT);
if(password_verify($password, $hashed)){
echo $hashed;
}
Also so würde ich jetzt den string "passwort" hashen mit etwas vollkommen zufälligem / salz und es zb auf meiner datenbank speicher, alles schön und gut.
Jetzt kommt das große aber, wenn ich die Seite von irgendwo anders aufrufe. Dann mich einloggen will wird das eingegebene wieder gehasht mit einem salz um es mit der sql datenbank abzugleichen.
Das geht aber garnicht weil dieses Salz doch immer ein anderer ist wenn ihr versteht was ich meine.
Hashes ohne salz vergleichen kriege ich schonmal ohne probleme hin.
zum beispiel so würde mein login/abgleich mit der datenbank aussehen :
if(isset($_POST["username"]) && isset($_POST["password"])){
$hash = hash("sha512", $_POST["password"]);
$mysqli1 = new mysqli($servername, $user, $pw, $db);
$result = $mysqli1->query('SELECT id FROM user WHERE username = "'. $_POST["username"]. '" ');
$result1 = $mysqli1->query('SELECT id FROM user WHERE password = "'. $hash. '" ');
if($result->num_rows == 1 and $result1->num_rows == 1 ) {
echo "Login erfolreich";
} else {
echo "Falsches Passwort oder Nutzername";
}
$mysqli1->close();
}
Hab jetzt mysqli benutzt weil es irgendwie übersichtlicher ist, und ob das anfällig für Sql Injections oder so ist spielt eigentlich keine rolle erstmal. Manche stört das
3 Antworten
Irgendwo hast du da einen Verständnisknick. Wie du schon richtig schreibst, ist es unsinnig, einen neuen Hash mit neuem Salt zu generieren, da dann ein Vergleich immer scheitern würde. Aber du musst überhaupt nicht solch einen Aufwand betreiben, denn die password_verfiy()-Methode bringt bereits alles vorgefertigt mit. Einfach das vom Benutzer eingegebene Passwort und den in der Datenbank hinterlegten Hashwert rein, und die Methode liefert dir zurück, ob das passt. Das sieht dann bspw. so aus:
<?php
if(isset($_POST["username"]) && isset($_POST["password"])) {
$mysqli1 = new mysqli($servername, $user, $pw, $db);
$result = $mysqli1->query('SELECT id, password FROM user WHERE username = "'. $_POST["username"]. '"');
$row = $result->fetch_assoc()
if ($row && password_verify($_POST["password"], $row["password"]) {
echo "Login erfolgreich";
} else {
echo "Falsches Passwort oder Nutzername";
}
$mysqli1->close();
}
Wegen SQL-Injections und ein paar veralteten Konzepten so natürlich nicht einsetzen, aber das ist dir ja bewusst.
Wenn du die password_hash-Funktion von PHP nutzt, wird intern automatisch ein zufälliger Salt generiert und mit in das Ergebnis eingebunden. Die password_verify-Funktion kann später den genutzten Salt wieder herauslesen und für die Prüfung einsetzen.
Fang also nicht damit an, das Rad neu zu erfinden, sondern nutze einfach nur diese beiden Funktionen. Weiteres dazu kannst du im Manual nachlesen.
Ganz einfach, das salt Speicherst du in Klartext irgendwo zusammen mit dem gehashten Passwort in der Datenbank.
Das ist wichtig, weil sonst hätte jeder nutzer mit dem selben passwort den selben hash, und außerdem könnte man einen hash ohne salt auch zur verifizierung bei anderen seiten verwenden die auch keinen salt nutzen.
Der ist teil des strings der da ausgegeben wird.
Mehmen wir z.B.
$2a$12$/7xWmKeGbrSEtPrmUeUdTO9VInoB8nuFG2vqhSqYIHR9KQpJiJBDK
2a ist die bcrypt version, 12 die kosten die du eingestellt hast.
Dann die ersten 22 zeichen(16 byte), also /7xWmKeGbrSEtPrmUeUdTO, sind der salt, und 9VInoB8nuFG2vqhSqYIHR9KQpJiJBDK der hash.
Das ist das gute bei bcrypt, da ist im prinzip alles an informationen was du zum verschlüsseln und entschlüsseln brauchst bereits im hash enthalten.
also so oder gibts was besseres?
$salt = substr($hashed,0, -22);
echo $salt;
hier nochmal alles:
<?php
$password = "passwort";
$hashed = password_hash($password, PASSWORD_DEFAULT);
$salt = substr($hashed,0, -22);
if(password_verify($password, $hashed)){
echo $hashed;
echo "<br> <br> ". $salt;
}
?>
Vorallem ist das falsch. Das salt sind die ersten 22 zeichen nach dem letzen dollarzeichen.
Wenn du das salt unbedingt wissen willst, wofür auch immer, musst du das so oder so ähnlich machen, ja. Weiß aber nicht wofür du das willst, wenn du nicht gerade eine eigeneImplementation von bcrypt schreiben willst...
Ich weiß halt nicht was du da komisches bauen willst...
Normal hashst halt das passwort, wenn man sich einloggen will packst du den hash und das eigegebene passwort in password_verify, Wenn das true ausgibt ist das Passwort halt richtig. Der hash enthält alle informationen, also sind keine weiteren Argumente bei der Verifizierung nötig.
Hmm,
Wie kann ich mir nur das Salt / PASSWORD_DEFAULT überhaupt anzeigen lassen von dem
?