How to select and validate encrypted password in PHP

Asked

Viewed 329 times

-1

Hello, I would like to know the best way to select and verify the password hash(password) in a database and compare with the password entered by the user in a login form. Is it more appropriate to store salt in the BD ? In the example below I created the password hash before selecting in the database:

<?php

include('conf.php');

$email = '[email protected]';
$senha = 'lala.123';
$custo = '08';
$salt = 'Cf1f11ePArKlBJomM0F6aJ';

$hash = crypt($senha, '$2a$' . $custo . '$' . $salt . '$');

    $query_select = "SELECT email, password FROM usuarios WHERE email = '$email' AND password = '$hash'";
    $select = mysqli_query($conexao,$query_select);

    if (mysqli_num_rows($select) == 1) {
        echo "Login Permitido";
    }
    else {
        echo "Login ou senha invalidos";
    } ?> 

Already in this example I selected the hash in the database to then compare with the password entered in the form using password_verify():

<?php 

#----------------- INCLUDING FILE --> "conf.php"
include('conf.php');

    if (isset($_POST['submit'])) {


        $email = mysqli_real_escape_string($conexao, $_POST['email']);
        $password = mysqli_real_escape_string($conexao, $_POST['password']);


        $query_select_email = "SELECT email FROM usuarios WHERE email = '$email'";
        $select_email = mysqli_query($conexao,$query_select_email);

        $query_select_password = "SELECT password FROM usuarios";
        $select_password = mysqli_query($conexao,$query_select_password);

        while($array = mysqli_fetch_array($select_password)) {
        $logarray = $array['password'];


            if (password_verify($password, $logarray) && mysqli_num_rows($select_email) == 1) {
                echo "Login permitido";

            }
        }
    } ?>

I accept any tip related to security and to improve the code, I thank you.

1 answer

0

The salt should be unique for each password, do $salt = 'Cf1f11ePArKlBJomM0F6aJ'; is somewhat useless, this would no longer be a salt and would become a pepper.

So, to answer the first question:

It is more appropriate to store salt in the BD ?

Yes. It is not only more appropriate... This is the very definition of salt, since it requires it to be unique by password, that is: for each password a different salt. Therefore it would be convenient to store the salt somewhere that has reference to the password hash, the database would be the most appropriate place in this case.


Already in this example I selected the hash in the database to then compare with the password entered in the form using password_verify()

The password_hash and password_verify is the recommended, it already stores the algorithm used, salt, and difficulty in the hash itself. Because of this, simply store the hash in the database and it contains the information needed to recalculate the hash, using the same algorithm, difficulty and salt. In addition, it internally generates a salt.

You can see more about it here.

I recommend that you change the Bcrypt to Argon2id, for this use the PASSWORD_ARGON2ID:

password_hash($senha, PASSWORD_ARGON2ID)

Note, that the algorithm is only defined at the time of hash creation and not in comparison, so you can change it without breaking the compatibilities with the already stored hashes, and to update the password algorithms you can use the passwod_needs_rehash, as users log in.

The password_hash There’s one problem, and that’s your low difficulty. By default, PHP, as smepre, defines an extremely low difficulty, you should adjust until it is comfortable (the higher the better, but there are chances of Dos and worsens the user experience). To adjust set:

password_hash($senha, PASSWORD_ARGON2ID, ['memory_cost' => 1<<17, 'time_cost' => 5, 'threads' => 2];

Change the memory cost, iteration cost, and number of threads, and test how long you can wait for the process.

The standard cost is:

memory_cost = 1024 KiB
time_cost = 2
threads = 2

Argon2id and Bcrypt have different difficulty settings.


Browser other questions tagged

You are not signed in. Login or sign up in order to post.