Funkcia password_hash

V skutočnosti sa funkcia md5 a solenie hesla s jej pomocou považuje za zastarané. Študovali sme ju, aby ste pochopili ďalšiu materiál, a tiež preto, že sa s tým môžete stretnúť pri práci na cudzích projektoch.

Existuje dokonalejší spôsob, ako získať solené heslo. Na to sa používa funkcia password_hash. Prvým parametrom prijíma reťazec a druhým - šifrovací algoritmus (o neskôr) a vráti hash tohto reťazca spolu so soľou.

Skúste niekoľkokrát spustiť tento kód:

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

Zakaždým dostanete iný výsledok a v tomto výsledku bude prvá časť reťazca predstavovať soľ, a druhá časť - solené heslo.

Predpokladajme, že máme hash získaný z funkcie password_hash a nejaké heslo. Aby sme skontrolovali, či je to hash tohto hesla alebo nie, mali by sme použiť funkciu password_verify - prvým parametrom prijíma heslo, a druhým - hash, a vráti true alebo false.

Pozrime sa na príklad:

html<?php
  $password = '12345'; // heslo
  $hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // hash
  
  if (password_verify($password, $hash)) {
    // hash od tohto hesla
  } else {
    // hash nie je od tohto hesla
  }
?>

Čo nám to dáva v praxi: môžeme v databáze nevytvárať samostatné pole pre ukladanie soli, nezaoberať sa generovaním tejto soli - PHP všetko spraví za nás!

To znamená, že v databáze v poli password budeme ukladať solené heslo spolu s jeho soľou. Pritom hashované heslo bude mať väčšiu dĺžku. Preto v databáze potrebujeme opraviť veľkosť poľa pre heslo a nastaviť ju na 60 znakov.

Teraz opravme kód registrácie. Tu je to, čo máme teraz:

html<?php
  function generateSalt()
  {
    $salt = '';
    $saltLength = 8; // dĺžka soli
    
    for($i = 0; $i < $saltLength; $i++) {
      $salt .= chr(mt_rand(33, 126)); // znak z ASCII tabuľky
    }
    
    return $salt;
  }
  
  $salt = generateSalt(); // soľ
  $password = md5($salt . $_POST['password']); // premeníme heslo na solený hash
?>

Pomocou password_hash to zredukujeme na:

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

Podobným spôsobom sa upraví kód autorizácie:

html<?php
  $login = $_POST['login'];
  
  $query = "SELECT * FROM users WHERE login='$login'"; // získame používateľa podľa loginu
  $res = mysqli_query($link, $query);
  $user = mysqli_fetch_assoc($res);
  
  if (!empty($user)) {
    $hash = $user['password']; // solené heslo z databázy
    
    // Kontrolujeme zhodu hashu z databázy so zadaným heslom
    if (password_verify($_POST['password'], $hash)) {
      // všetko v poriadku, autorizujeme...
    } else {
      // heslo nesedí, vypíšeme správu
    }
  } else {
    // používateľ s takýmto loginom neexistuje, vypíšeme správu
  }
?>
Задание 1

Upravte vašu autorizáciu a registráciu na novo naučené funkcie.