Funkce password_hash
Ve skutečnosti se funkce md5 a solení
hesla s její pomocí považuje za zastaralé.
Studovali jsme ji, abyste pochopili další
materiál, a také proto, že se s tím můžete setkat
při práci s cizími projekty.
Existuje dokonalejší způsob, jak získat
solené heslo. K tomu se používá funkce
password_hash. Prvním parametrem
přijímá řetězec a druhým - šifrovací algoritmus
(o něm později) a vrací hash tohoto řetězce
společně se solí.
Zkuste několikrát spustit tento kód:
<?php
echo password_hash('12345', PASSWORD_DEFAULT);
?>
Pokaždé dostanete jiný výsledek a v tomto výsledku bude první část řetězce představovat sůl a druhá část - solené heslo.
Předpokládejme, že máme hash získaný z funkce
password_hash a nějaké heslo. Abyste
zkontrolovali, zda je to hash tohoto hesla nebo ne,
měli byste použít funkci password_verify
- prvním parametrem přijímá heslo,
a druhým - hash, a vrací true
nebo false.
Podívejme se na příklad:
<?php
$password = '12345'; // heslo
$hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // hash
if (password_verify($password, $hash)) {
// hash z tohoto hesla
} else {
// hash není z tohoto hesla
}
?>
Co nám to dává v praxi: můžeme v databázi nevytvářet samostatné pole pro ukládání soli, nezatěžovat se generováním této soli - PHP vše udělá za nás!
To znamená, že v databázi v poli
password budeme ukládat solené
heslo společně s jeho solí. Přitom hashované
heslo bude mít větší délku. Proto
v databázi potřebujeme opravit velikost
pole pro heslo a nastavit ji na 60
znaků.
Nyní opravme kód registrace. Zde je to, co máme nyní:
<?php
function generateSalt()
{
$salt = '';
$saltLength = 8; // délka soli
for($i = 0; $i < $saltLength; $i++) {
$salt .= chr(mt_rand(33, 126)); // znak z ASCII tabulky
}
return $salt;
}
$salt = generateSalt(); // sůl
$password = md5($salt . $_POST['password']); // převedeme heslo na solený hash
?>
Pomocí password_hash to zkrátíme na:
<?php
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
?>
Podobným způsobem se upraví kód autorizace:
<?php
$login = $_POST['login'];
$query = "SELECT * FROM users WHERE login='$login'"; // získáme uživatele podle přihlašovacího jména
$res = mysqli_query($link, $query);
$user = mysqli_fetch_assoc($res);
if (!empty($user)) {
$hash = $user['password']; // solené heslo z databáze
// Kontrolujeme shodu hashe z databáze se zadaným heslem
if (password_verify($_POST['password'], $hash)) {
// vše v pořádku, autorizujeme...
} else {
// heslo nesedí, vypíšeme zprávu
}
} else {
// uživatel s tímto přihlašovacím jménem neexistuje, vypíšeme zprávu
}
?>
Přepracujte vaši autorizaci a registraci na nové probrané funkce.