4

I get this assignment and until now, I was using sha1 for security. The teacher got back to us last friday and told us to use password_hash. Knowing it's for tomorrow, I tried to figure out how this works but don't wrap my head around it. I found many people talking about it but none of these worked for me: How to use password_hash Register And Login

Currently, as it was assigned, I am only using PDO and got back to my previous working code (with sha1)

    <?php
    ob_start();// TEST
    include("inc/timer.inc.php");//session
    require("inc/database.inc.php");//connection website
    $title='website';

    if (isset($_POST['formConnection'])) {
    $loginConnection = filter_input(INPUT_POST, 'loginConnection', FILTER_SANITIZE_FULL_SPECIAL_CHARS   );

    // Connection sha1- OLD
    $passwordConnection = sha1($_POST['passwordConnection']);

    // Connection password_hash
    //$hash = $profile['password'];
    //$passwordConnection = password_verify($_POST['passwordConnection'], $hash);

        if (!empty(($loginConnection) AND !empty($passwordConnection))) {
            $connection = $website->prepare("SELECT * FROM members WHERE login = ? AND password= ?");
            $connection->execute(array($loginConnection, $passwordConnection));
            $userExists = $connection->rowCount(); //Test existence et affectation à la session des valeurs

            if ($userExists == 1) {
            $profile = $connection->fetch();
            $_SESSION['idMember'] = $profile['idMember'];
            $_SESSION['login'] = $profile['login'];
            $_SESSION['status'] = $profile['status'];
            header("Location: member-detail.php?idMember=".$_SESSION['idMember']);
            } else {
            echo "<script>alert(\"Wrong login or password\")</script>"; 
            }

        } else {
        echo "<script>alert(\"Please check your login or your password\")</script>"; 
        }

    }
    ?>
    <body>

        <form method="post" action="">

            <div class="form-group">
                <label for="loginConnection">login</label><br>
                <input type="text" class="form-control" name="loginConnection" id="loginConnection"
                    placeholder="login" required><br><br>
            </div>

            <div class="form-group">
                <label for="passwordConnection">password</label><br>
                <input type="password" class="form-control" name="passwordConnection" id="passwordConnection"
                    placeholder="Mot de Passe" required><br><br>
            </div>
            <input type="submit" name="formConnection" value="Se connecter">

            <div class="form-group">
                <a href="subscribe.php">Not subscribed yet?</a>
            </div>

        </form>
        <br><br>

    </body>

I know it's supposed to be a boolean but I cannot figure out how to use it.

Is there a step-by-step tutorial for this? I might have missed it. Thanks

LucasClement
  • 63
  • 1
  • 5
  • 2
    [password_verify()](http://php.net/manual/en/function.password-verify.php) – Dharman Jan 21 '19 at 20:05
  • I am voting to close your question as a duplicate, because it is too broad and has already been answered before multiple times, even in PHP manual itself. However if you have a valid problem/error you can edit your question and focus on a single issue. We would be glad to help. – Dharman Jan 21 '19 at 20:09
  • First pull the users data out (of the DB) by login (without using password) then take the hash from DB and compare that to the form input with `password_verify`. It's actually insecure to compare hashes with a DB query, Just one example: DB searches are not (typically) case sensitive in MySQL but hashes are. Therefor there is a very slight chance you could have 2 hashes that collide (are seen as the same) because of casing. – ArtisticPhoenix Jan 21 '19 at 20:22
  • This may seem trivial but consider the implications when brute forcing said password. Now instead of one hash that matches in sha1, you have well more then 2^40 (I think, anyway it's a lot more then 1) that would match, just because of casing issues. – ArtisticPhoenix Jan 21 '19 at 20:28

2 Answers2

3

The password_verify() function is to be used in conjunction with the password_hash() function.

You store the hash generated from password_hash() in your database . When someone tries to log in, you test the password they provided against the hash. If password_verify() returns true, the password matches.

You should not rehash the password yourself with password_hash() because you will get a different answer every time (if using a random salt, which you should). When you hash the password using password_hash(), it, by default, uses a random salt to hash it. This random salt is encoded into the resulting hash string so that password_verify() can verify it using the same salt as it was originally hashed with.

Basically, you should retrieve the hash from the database for the user trying to log in, and supply it to the password_verify() function. Along with the salt, the hash also contains information as to which hash algorythm was used.

php.net example

<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>
Kenneth
  • 535
  • 2
  • 17
  • You have copied another answer from SO. We do not do that here. If there is already an answer available we close as a duplicate. – Dharman Jan 21 '19 at 20:12
  • Huh? I wrote that from scratch, minus copying the example – Kenneth Jan 21 '19 at 20:16
  • Do you feel that your answer is better than the other answer you copied from? Even the comment in the code makes no sense, because you copied a small fragment of the other answer. – Dharman Jan 21 '19 at 20:17
  • Actually, that is the full one and only example from PHP's own website.http://php.net/manual/en/function.password-verify.php, so you can take your down vote back now, please – Kenneth Jan 21 '19 at 20:18
  • You can improve the answer, if you want to make it better. Include the example how to use `password_hash`, add links to PHP manual, point out that OP is using password field in the select query, warn them about minimum length for VARCHAR. At the moment your answer is not much more helpful than PHP manual. – Dharman Jan 21 '19 at 20:24
1

You have to get the user from the db and then check the password with password_verify. So, just SELECT * FROM members WHERE login = ?, then inside your if ($userExists == 1) { fail the login if password_verify($_POST['passwordConnection'], $profile['password') is false.

Sheldon R
  • 124
  • 1
  • 5