Funkcija password_hash

Pravzaprav se funkcija md5 in soljenje gesla z njo štejeta za zastareli. Učili smo se je, da bi razumeli nadaljnjo snterial, pa tudi zato, ker se lahko s tem srečate pri delu s tujimi projekti.

Obstaja bolj popoln način za pridobitev posoljenega gesla. Za to se uporablja funkcija password_hash. Kot prvi parameter sprejme niz, kot drugega pa algoritem šifriranja (o tem kasneje), in vrne zgoščeno vrednost tega niza skupaj s soljo.

Poskusite večkrat zagnati to kodo:

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

Vsakič boste dobili drugačen rezultat in v tem rezultatu bo prvi del niza predstavljal sol, drugi del pa posoljeno geslo.

Recimo, da imamo zgoščeno vrednost, pridobljeno s funkcijo password_hash, in neko geslo. Da preverimo, ali je to zgoščena vrednost tega gesla ali ne, je treba uporabiti funkcijo password_verify - kot prvi parameter sprejme geslo, kot drugega pa zgoščeno vrednost, in vrne true ali false.

Poglejmo si primer:

html<?php
  $password = '12345'; // geslo
  $hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // zgoščenka
  
  if (password_verify($password, $hash)) {
    // zgoščenka tega gesla
  } else {
    // zgoščenka ni tega gesla
  }
?>

Kaj nam to daje v praksi: lahko ne ustvarimo ločenega polja v podatkovni bazi za shranjevanje soli, se ne ukvarjamo z generiranjem te soli - PHP bo vse naredil namesto nas!

To pomeni, da bomo v podatkovni bazi v polju password shranjevali posoljeno geslo skupaj z njegovo soljo. Pri tem bo zgoščeno geslo imelo večjo dolžino. Zato moramo v podatkovni bazi popraviti velikost polja za geslo in jo nastaviti na 60 znakov.

Zdaj pa popravimo kodo za registracijo. Tukaj je, kar imamo zdaj:

html<?php
  function generateSalt()
  {
    $salt = '';
    $saltLength = 8; // dolžina soli
    
    for($i = 0; $i < $saltLength; $i++) {
      $salt .= chr(mt_rand(33, 126)); // znak iz ASCII-tabele
    }
    
    return $salt;
  }
  
  $salt = generateSalt(); //  sol
  $password = md5($salt . $_POST['password']); // pretvorimo geslo v posoljeno zgoščenko
?>

Z password_hash bomo to skrajšali na:

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

Podobno se bo popravila tudi koda za prijavo:

html<?php
  $login = $_POST['login'];
  
  $query = "SELECT * FROM users WHERE login='$login'"; // dobimo uporabnika po prijavnem imenu
  $res = mysqli_query($link, $query);
  $user = mysqli_fetch_assoc($res);
  
  if (!empty($user)) {
    $hash = $user['password']; // posoljeno geslo iz baze
    
    // Preverimo ujemanje zgoščenke iz baze z vnešenim geslom
    if (password_verify($_POST['password'], $hash)) {
      // vse je v redu, prijavimo...
    } else {
      // geslo se ni ujemalo, izpišemo sporočilo
    }
  } else {
    // uporabnika s takšnim prijavnim imenom ni, izpišemo sporočilo
  }
?>
Задание 1

Predelajte vašo prijavo in registracijo z na novo preučenimi funkcijami.