Funkcija password_hash

Iš tiesų funkcija md5 ir slaptažodžio "druskos" pritaikymas su ja laikomi pasenusiais. Mes ją tyrėme, kad jūs suprastumėte tolesnę medžiagą, taip pat dėl to, kad su tuo galite susidurti dirbdami su svetimais projektais.

Yra tobulesnis būdas gauti "pradruskintą" slaptažodį. Tam naudojama funkcija password_hash. Pirmuoju parametru ji priima eilutę, o antruoju - šifravimo algoritmą (apie jį vėliau), ir grąžina šios eilutės maišą kartu su "druska".

Pabandykite kelis kartus paleisti šį kodą:

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

Kaskart gausite skirtingą rezultatą ir šiame rezultate pirmoji eilutės dalis bus "druska", o antroji dalis - "pradruskintas" slaptažodis.

Tarkime, mes turime maišą, gautą iš funkcijos password_hash ir kažkokį slaptažodį. Kad patikrintumėte, ar tai šio slaptažodžio maišas, ar ne, reikia naudoti funkciją password_verify - pirmuoju parametru ji priima slaptažodį, o antruoju - maišą, ir grąžina true arba false.

Pažiūrėkime pavyzdžiu:

html<?php
  $password = '12345'; // slaptažodis
  $hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // maišas
  
  if (password_verify($password, $hash)) {
    // maišas iš šio slaptažodžio
  } else {
    // maišas ne iš šio slaptažodžio
  }
?>

Ką tai mums duoda praktiškai: mes galime nekurti duomenų bazėje atskiro lauko "druskos" saugojimui, nesivarginti su šios "druskos" generavimu - PHP viską padarys už mus!

Tai reiškia, kad duomenų bazėje lauke password mes saugosime "pradruskintą" slaptažodį kartu su jo "druska". Tuo tarpu maišytas slaptažodis turės didesnį ilgį. Todėl duomenų bazėje mums reikia pataisyti dydį slaptažodžio lauko ir nustatyti jį į 60 simbolių.

Dabar pataisykime registracijos kodą. Štai kas yra dabar:

html<?php
  function generateSalt()
  {
    $salt = '';
    $saltLength = 8; // "druskos" ilgis
    
    for($i = 0; $i < $saltLength; $i++) {
      $salt .= chr(mt_rand(33, 126)); // simbolis iš ASCII lentelės
    }
    
    return $salt;
  }
  
  $salt = generateSalt(); //  "druska"
  $password = md5($salt . $_POST['password']); // paverčiame slaptažodį į "pradruskintą" maišą
?>

Naudodami password_hash mes tai sutrumpiname iki:

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

Analogiskai pataisomas ir autorizacijos kodas:

html<?php
  $login = $_POST['login'];
  
  $query = "SELECT * FROM users WHERE login='$login'"; // gauname vartotoją pagal prisijungimo vardą
  $res = mysqli_query($link, $query);
  $user = mysqli_fetch_assoc($res);
  
  if (!empty($user)) {
    $hash = $user['password']; // "pradruskintas" slaptažodis iš DB
    
    // Tikriname maišo iš duomenų bazės atitikimą įvestam slaptažodžiui
    if (password_verify($_POST['password'], $hash)) {
      // viskas gerai, autorizuojame...
    } else {
      // slaptažodis netiko, išvesime pranešimą
    }
  } else {
    // vartotojo su tokiu prisijungimo vardu nėra, išvesime pranešimą
  }
?>
Задание 1

Perdarykite savo autorizaciją ir registraciją naudodami naujai išmoktas funkcijas.