Функција 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 табеле
    }
    
    return $salt;
  }
  
  $salt = generateSalt(); //  солa
  $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

Промените вашу аутентификацију и регистрацију на нове научене функције.