Функция password_hash

Всъщност функцията md5 и соленето на парола с нейна помощ се счита за остаряла. Учихме я, за да разберете следвания материал, а също и защото може да се сблъскате с нея, работейки с чужди проекти.

Съществува по-съвършен начин за получаване на солена парола. За това се използва функцията password_hash. Първият параметър, който тя приема, е низ, а вторият - алгоритъм за криптиране (за него по-късно), и връща хеша на този низ заедно със сол.

Опитайте да стартирате този код няколко пъти:

html<?php
  echo password_hash('12345', PASSWORD_DEFAULT);
?>

Всеки път ще получавате различен резултат и в този резултат първата част от низа ще бъде солта, а втората част - солената парола.

Да кажем, че имаме хеш, получен от функцията password_hash и някаква парола. За да проверим дали това е хешът на тази парола или не, трябва да използваме функцията password_verify - първият параметър, който тя приема, е паролата, а вторият - хешът, и връща true или false.

Нека разгледаме пример:

html<?php
  $password = '12345'; // парола
  $hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // хеш
  
  if (password_verify($password, $hash)) {
    // хеш от тази парола
  } else {
    // хеш не е от тази парола
  }
?>

Какво ни дава това на практика: можем да не създаваме отделно поле в базата данни за съхранение на солта, да не се занимаваме с генерирането на тази сол - PHP ще направи всичко вместо нас!

Тоест ще се получи, че в базата данни в полето password ще съхраняваме солената парола заедно с нейната сол. При това хешираната парола ще има по-голяма дължина. Затова в базата данни трябва да коригираме размера на полето с парола и да я зададем на 60 символа.

Сега нека поправим кода за регистрация. Ето какво имаме в момента:

html<?php
  function generateSalt()
  {
    $salt = '';
    $saltLength = 8; // дължина на солта
    
    for($i = 0; $i < $saltLength; $i++) {
      $salt .= chr(mt_rand(33, 126)); // символ от ASCII-table
    }
    
    return $salt;
  }
  
  $salt = generateSalt(); //  сол
  $password = md5($salt . $_POST['password']); // преобразуваме паролата в солен хеш
?>

С помощта на password_hash ще съкратим това до:

html<?php
  $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
?>

По подобен начин се коригира кодът за авторизация:

html<?php
  $login = $_POST['login'];
  
  $query = "SELECT * FROM users WHERE login='$login'"; // получаваме потребителя по логин
  $res = mysqli_query($link, $query);
  $user = mysqli_fetch_assoc($res);
  
  if (!empty($user)) {
    $hash = $user['password']; // солена парола от БД
    
    // Проверяваме съответствието на хеша от базата с въведената парола
    if (password_verify($_POST['password'], $hash)) {
      // всичко е наред, авторизираме...
    } else {
      // паролата не съвпада, извеждаме съобщение
    }
  } else {
    // няма потребител с такъв логин, извеждаме съобщение
  }
?>
Задание 1

Променете вашата авторизация и регистрация да използват новите изучени функции.