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:

html<?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:

html<?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í:

html<?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:

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

Podobným způsobem se upraví kód autorizace:

html<?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
  }
?>
Задание 1

Přepracujte vaši autorizaci a registraci na nové probrané funkce.