Ik zie dat u een hash van het wachtwoord in de database opslaat, maar nooit ten behoeve van andere lezers bewaar wachtwoorden in platte tekst in de database. Je wilt geen zoals Monster.com.uk !
U moet een sterkere hash-functie gebruiken dan MD5()
. Idealiter zou u SHA256 moeten gebruiken. Deze hash-methode is beschikbaar in PHP met behulp van de hash()
functie.
Je moet ook een willekeurige zout toepassen naar het wachtwoord. Sla een andere zoutwaarde op voor het account van elke gebruiker. Dit helpt om woordenboekaanvallen en regenboogtabel te verslaan aanvallen.
U moet de mysqli leren gebruiken extensie in plaats van de oude mysql-extensie. Mysqli ondersteunt geparametriseerde zoekopdrachten, zodat u de kwetsbaarheid voor sommige SQL-injectie-aanvallen kunt verminderen.
Hier is een voorbeeldcode. Ik heb het niet getest, maar het zou bijna moeten werken:
$input_login = $_POST['login'];
$input_password = $_POST['password'];
$stmt = $mysqli->prepare("SELECT password, salt FROM customer WHERE login = ?");
$stmt->bind_param("s", $input_login);
$stmt->execute();
$stmt->bind_result($password_hash, $salt);
while ($stmt->fetch()) {
$input_password_hash = hash('sha256', $input_password . $salt);
if ($input_password_hash == $password_hash) {
return true;
}
// You may want to log failed password attempts here,
// for security auditing or to lock an account with
// too many attempts within a short time.
}
$stmt->close();
// No rows matched $input_login, or else password did not match
return false;
Sommige andere mensen stellen voor dat de query moet testen op login = ? AND password = ?
maar dat doe ik niet graag. Als u dit doet, weet u niet of het opzoeken is mislukt omdat de aanmelding niet bestond of omdat de gebruiker een verkeerd wachtwoord heeft opgegeven.
Natuurlijk mag u niet aan de gebruiker onthullen wat de mislukte inlogpoging heeft veroorzaakt, maar u moet u mogelijk weten, zodat u verdachte activiteiten kunt registreren.
@Javier zegt in zijn antwoord dat je het wachtwoord (of in dit geval de wachtwoordhash) niet uit de database moet halen. Ik ben het er niet mee eens.
Javier laat zien dat hij md5()
. aanroept in PHP-code en het verzenden van de resulterende hash-string naar de database. Maar dit ondersteunt niet het gemakkelijk zouten van het wachtwoord. Je moet een aparte query doen om het salt van deze gebruiker op te halen voordat je de hash in PHP kunt doen.
Het alternatief is het verzenden van de platte tekst wachtwoord via het netwerk van uw PHP-app naar uw databaseserver. Iedereen die je netwerk aftapt, kan dit wachtwoord zien. Als er SQL-query's worden vastgelegd, kan iedereen die toegang krijgt tot de logboeken het wachtwoord zien. Gemotiveerde hackers kunnen zelfs dumpster-duiken om oude back-upmedia van het bestandssysteem te vinden, en kunnen de logbestanden op die manier lezen!
Het kleinere risico is om de wachtwoordhashstring uit de database op te halen in de PHP-app, deze te vergelijken met de hash van de invoer van de gebruiker (ook in PHP-code) en deze variabelen vervolgens weg te gooien.