Função password_hash

Na verdade, a função md5 e salgar a senha com ela é considerado ultrapassado. Nós a estudamos para que você entendesse o material seguinte, e também porque você pode se deparar com isso ao trabalhar em projetos de terceiros.

Existe uma maneira mais avançada de obter uma senha salgada. Para isso, usa-se a função password_hash. No primeiro parâmetro ela recebe uma string, e no segundo - o algoritmo de criptografia (sobre isso depois), e retorna o hash dessa string juntamente com o salt.

Tente executar este código várias vezes:

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

Você obterá um resultado diferente a cada vez e, neste resultado, a primeira parte da string será o salt, e a segunda parte - a senha com salt.

Suponha que temos um hash obtido da função password_hash e alguma senha. Para verificar se é o hash dessa senha ou não, devemos usar a função password_verify - no primeiro parâmetro ela recebe a senha, e no segundo - o hash, e retorna true ou false.

Vejamos um exemplo:

html<?php
  $password = '12345'; // senha
  $hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // hash
  
  if (password_verify($password, $hash)) {
    // hash é desta senha
  } else {
    // hash não é desta senha
  }
?>

O que isso nos dá na prática: podemos não criar um campo separado no banco de dados para armazenar o salt, não nos preocupar em gerar esse salt - o PHP fará tudo por nós!

Ou seja, no banco de dados, no campo password armazenaremos a senha com salt juntamente com seu salt. Ao mesmo tempo, a senha com hash terá um comprimento maior. Portanto, no banco de dados precisamos corrigir o tamanho do campo da senha e defini-lo para 60 caracteres.

Agora vamos corrigir o código de registro. Eis o que temos atualmente:

html<?php
  function generateSalt()
  {
    $salt = '';
    $saltLength = 8; // comprimento do salt
    
    for($i = 0; $i < $saltLength; $i++) {
      $salt .= chr(mt_rand(33, 126)); // caractere da tabela ASCII
    }
    
    return $salt;
  }
  
  $salt = generateSalt(); //  salt
  $password = md5($salt . $_POST['password']); // transformamos a senha em hash com salt
?>

Usando password_hash podemos reduzir isso para:

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

Da mesma forma, o código de login será ajustado:

html<?php
  $login = $_POST['login'];
  
  $query = "SELECT * FROM users WHERE login='$login'"; // obtemos o usuário pelo login
  $res = mysqli_query($link, $query);
  $user = mysqli_fetch_assoc($res);
  
  if (!empty($user)) {
    $hash = $user['password']; // senha com salt do Banco de Dados
    
    // Verificamos a correspondência do hash do banco com a senha inserida
    if (password_verify($_POST['password'], $hash)) {
      // está tudo ok, autenticar...
    } else {
      // a senha não conferiu, exibir mensagem
    }
  } else {
    // não há usuário com este login, exibir mensagem
  }
?>
Задание 1

Modifique seu sistema de login e registro para usar as novas funções estudadas.