Never, never, but never save passwords in sessions, no matter how safe your sessions may seem.
To check a hash, with bcrypt, you should simply provide the first hash(hash in the database) and encrypt the password coming from the form (in your case, the hash stored in the session).
<?php
// See the password_hash() example to see where this came from.
// a variavel hash possui o valor da hash no banco de dados
// Imagine que este é o valor
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
// So para relembrar, que guardar senhas na sessão nao é uma boa pratica.
if (password_verify($_SESSION['senha_na_sessao'], $hash)) {
echo 'Password is valid!';
// Usuario autenticado
// Inicializar as sessoes para esse usuario
} else {
echo 'Invalid password.';
// Usuario invalido
// Retorna a pagina de login
}
?>
The function password_verify is unique to PHP >= 5.5.0
For PHP versions below PHP < 5.5.0 there is this API simulating these new functions.
An example:
<?php
//Reset dos valores
$usr = $pwd = "";
// Cadastro
if(isset($_POST["cadastrar"])){
// Neste exemplo, não irei verificar se o usuario digitou algo ou nao
if(isset($_POST["usuario"]) && isset($_POST["senha"])){
$usr = $_POST["usuario"];
$pwd = $_POST["senha"];
// A partir daqui tratamos da senha
// Encripta-se a senha;
// esta funcao utiliza o blowfish por predefinicao
$hash = password_hash($pwd, PASSWORD_DEFAULT);
if($hash){
// Insere no banco de dados
// Um exemplo:
$query = "INSERT INTO usuarios ('nome','senha') VALUES ('{$usr}','{$hash}') LIMIT 1";
if(mysqli_query($conexao_sqli, $query)){
echo "Cadastrado";
// redirecciona
} else {
echo "Não cadastrado";
// redirecciona
exit;
}
// Encerra a conexao algures
}
}
}
// Login
if(isset($_POST["entrar"])){
// Neste exemplo, não irei verificar se o usuario digitou algo ou nao
if(isset($_POST["usuario"]) && isset($_POST["senha"])){
$usr = $_POST["usuario"];
$pwd = $_POST["senha"];
// A partir daqui tratamos da senha
// Aqui faz-se a mesma, coisa, mas desta vez utiliza-se
// a hash do banco de dados
// O blowfish utiliza apenas os 22 primeiros carateres
// para criar a hash
// Uma consulta SQL/funcao que retorna a hash no banco
// de dados passa este usuario
// exemplo:
$query = "SELECT nome, senha FROM usuarios WHERE usuario = '{$usr}'";
$if(mysqli_query($conexao_sqli, $query)){
$hash_do_banco_de_dados = mysqli_fetch_assoc($query);
$hash = password_hash($pwd, $hash_do_banco_de_dados["senha"]);
if($hash){
if(password_verify($pwd, $hash)){
echo "Logado";
// Sessoes
// Redirecciona
exit;
} else {
echo "Nao logado";
// redirecciona
exit;
}
}
}
}
}
?>
<?php
if(!isset($_GET['pagina']) && $_GET['pagina'] == 'cadastrar'){
?>
<form method="POST" action="">
Usuario:<br/>
<input type="text" name="usuario" size="30"/><br/>
Senha:<br/>
<input type="password" name="senha" size="30"/><br/>
<input type="submit" name="cadastrar" value="Cadastrar"/>
</form>
<br/>
<br/>
Clique aqui para <a href="index.php?pagina=entrar">Entrar</a>
<?php
} elseif(isset($_GET['pagina']) && $_GET['pagina'] == 'entrar'){
?>
<form method="POST" action="">
Usuario:<br/>
<input type="text" name="usuario" size="30"/><br/>
Senha:<br/>
<input type="password" name="senha" size="30"/><br/>
<input type="submit" name="entrar" value="Entrar"/>
</form>
<br/>
<br/>
Clique aqui para <a href="index.php?pagina=cadastrar">cadastrar</a>
<?php
} else {
?>
<form method="POST" action="">
Usuario:<br/>
<input type="text" name="usuario" size="30"/><br/>
Senha:<br/>
<input type="password" name="senha" size="30"/><br/>
<input type="submit" name="entrar" value="Entrar"/>
</form>
<br/>
<br/>
Clique aqui para <a href="index.php?pagina=cadastrar">Cadastrar</a>
<?php>
}
?>
That’s basically it, I took some time to create this, because I created it from gedit and also because I’m by linux in a notebook :/ but I couldn’t run the example, but I guarantee it works, it will be enough that you replace the variables of fiticias connection that I used in the example.
Samuel, I deleted my comment for not bringing anything relevant to the question... but about bcrypt here is a tutorial on the use of it: http://blog.thiagobelem.net/encryptando-passwordsno-php-usando-bcrypt-blowfish/
– Rafael Withoeft
@Rafaelwithoeft I was following this tutorial, but there it does not explain how to use it in Session and mysql, because to check if the two data are equals, one of the values that has q be passed to the function, has q be the password without being encrypted, and the already encrypted password that comes from the database. Only in my case, the two passwords are encrypted. There is some way to make this login system without using Session?
– Samuel Carvalho
There are several ways, I don’t particularly store passwords in session... just a user ID normally. Here is a question that involves this session and login question: http://answall.com/questions/38920/o-que-guardar-uma-sess%C3%A3o-login do you use bcrypt with dynamic salt ? What you can do maybe is: store the session in the database (table - memory), and in critical areas you ask for the password again...
– Rafael Withoeft
But going back to the focus of your question, before storing in the session you pass the password again by a bcrypt function, thus generating a different value than can be on the right basis? If you compare what you have in the value session will be different from the base then... (At least that’s what I understood, I’m just confirming this information)
– Rafael Withoeft
@Rafaelwithoeft That’s right, and since the two passwords, both the one in the database and the one saved in Ssion, are encrypted in bcrypt, I can’t verify that the two are equal, because to do this check, I need the original password without being encrypted, but saving these password in Sesssion without encryption gets very insecure.
– Samuel Carvalho
Samuel, I understand you’re using a fixed salt, right? What you can do to not store passwords without security there is, generate a hash, leave it in the session and add it in a table in the database that will take care of the sessions (memory table), you validate if this hash exists in the base, otherwise you ask for the password again, and for critical system places you ask for password confirmation even logged in and when the session expires or the user leaves you delete this hash from the table. It is one of the ways, otherwise you just check if there is session and let the user follow...
– Rafael Withoeft
@Rafaelwithoeft no, I’m using a dynamic salt. I understood the method you said, but I didn’t understand how to check if user is logged in with the memory table. If you don’t mind, you can show me a small example of this php check?
– Samuel Carvalho
Samuel http://chat.stackexchange.com/rooms/22834/verifica-session
– Rafael Withoeft
@Rafaelwithoeft thank you very much, gave to understand now. I will do this way from now on.
– Samuel Carvalho