User authentification / login issue (password hash)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Publisher Bucks
    Confirmed User
    • Oct 2018
    • 1330

    #1

    Tech User authentification / login issue (password hash)

    I have no issues with inserting the data into the database, the signup form is working perfectly however, when trying to login the page keeps telling me that the user/pass is incorrect and I can't figure out why.

    Im creating a session, pulling the fields from the database correctly and having looking in the SQL row, the passwords are being stored correctly.

    Could someone point me in the right direction with the code below as to why this isnt working?

    <?php
    session_start();
    $DATABASE_HOST = 'localhost';
    $DATABASE_USER = 'user';
    $DATABASE_PASS = 'pass';
    $DATABASE_NAME = 'db';
    // Try and connect using the info above.
    $con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
    if ( mysqli_connect_errno() ) {

    exit('Failed to connect to MySQL: ' . mysqli_connect_error());
    }

    if ($stmt = $con->prepare('SELECT id, password FROM Register WHERE username = ?')) {
    $stmt->bind_param('s', $_POST['username']);
    $stmt->execute();
    if ($stmt->num_rows > 0) {
    $stmt->bind_result($id, $password);
    $stmt->fetch();
    if ($_POST['password'] === $password) {
    session_regenerate_id();
    $_SESSION['loggedin'] = TRUE;
    $_SESSION['name'] = $_POST['username'];
    $_SESSION['id'] = $id;
    echo 'Welcome ' . $_SESSION['name'] . '!';
    } else {
    // Wrong password
    echo 'Incorrect User/Pass!';
    }
    } else {
    // Wrong username
    echo 'Incorrect User/Pass!';
    }
    $stmt->store_result();
    $stmt->close();
    }
    ?>
    /
    This isnt for anything fancy, just trying to have a system when employees can maintain their contact information and keep it up to date.

    *Quick Edit*

    I'm using this on the submission form for the password, if it matters.

    $secure_pass = password_hash($password, PASSWORD_BCRYPT);
    Extreme Link List - v1.0
  • zijlstravideo
    Confirmed User
    • Sep 2013
    • 806

    #2
    You want to grab the clean user input (aka the password the user typed in), then compare that to the hash (in the database), I assume?

    But here you are comparing the user input to $password (which is the hash/SQL entry, I guess?).

    Shouldn't it be more like this this, in that case:

    if (password_hash($_POST['password'], PASSWORD_BCRYPT) === $password)
    {
    ....
    }
    Contact: email

    Comment

    • zijlstravideo
      Confirmed User
      • Sep 2013
      • 806

      #3
      Or... do you take the user input (password) from the form, then hash it using Bcrypt, before submitting the form?

      It's a bit of a weird logic. Usually you take the raw input on submit, then after submit you'd hash it and compare those two hashes.

      I think the problem now might be this: If the password is 'dildo', the Bcrypt hash is '$2a$10$F0eXLChOzrgQXlIL0hFdxOVQ9Y6it3dXIRGueIB54t cHqPvUUeUMO'

      When you take that hash as input using $_POST, isn't php replacing the $2a, $10 parts etc with nothing, because these variables don't exists?
      Contact: email

      Comment

      • sarettah
        see you later, I'm gone
        • Oct 2002
        • 14297

        #4
        Originally posted by zijlstravideo
        if (password_hash($_POST['password'], PASSWORD_BCRYPT) === $password)
        {
        ....
        }
        This ^^^^^
        All cookies cleared!

        Comment

        • Publisher Bucks
          Confirmed User
          • Oct 2018
          • 1330

          #5
          Originally posted by zijlstravideo
          Or... do you take the user input (password) from the form, then hash it using Bcrypt, before submitting the form?
          Yes, the user submits their required password and i encrypt it through submit.php when it gets written to the database.

          Here is the submit.php file that sends data to SQL...

          <?php

          /* Attempt MySQL server connection.
          $link = mysqli_connect("localhost", "user", "pass", "db");

          // Check connection
          if($link === false){
          die("ERROR: Could not connect. " . mysqli_connect_error());
          }

          // Escape user inputs for security
          $id = mysqli_real_escape_string($link, $_REQUEST['id']);
          $name = mysqli_real_escape_string($link, $_REQUEST['name']);
          $email = mysqli_real_escape_string($link, $_REQUEST['email']);
          $username = mysqli_real_escape_string($link, $_REQUEST['username']);
          $password = mysqli_real_escape_string($link, $_REQUEST['password']);
          $phone = mysqli_real_escape_string($link, $_REQUEST['phone']);

          // Securing password using password_hash
          $secure_pass = password_hash($password, PASSWORD_BCRYPT);


          // Attempt insert query execution
          $sql = "INSERT INTO Register (name, email, username, password, phone) VALUES ('$name', '$email', '$username', '$secure_pass', '$phone')";
          if(mysqli_query($link, $sql)){
          echo "";

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

          $email_from="user.com";
          $email_to="me.com";
          $email_subject="New Update";

          // create email headers
          $headers = 'From: '.$email_from."\r\n".
          'Reply-To: '.$email_from."\r\n" .
          'X-Mailer: PHP/' . phpversion();
          @mail($email_to, $email_subject, $headers);

          }

          } else{
          echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
          }

          // Close connection
          mysqli_close($link);
          ?>
          I beleive the part in bold should be doing the encrypting correctly and storing it in the 'password' column in the table that im calling from the login script?
          Extreme Link List - v1.0

          Comment

          • sarettah
            see you later, I'm gone
            • Oct 2002
            • 14297

            #6
            Originally posted by Publisher Bucks
            Yes, the user submits their required password and i encrypt it through submit.php when it gets written to the database.

            Here is the submit.php file that sends data to SQL...



            I beleive the part in bold should be doing the encrypting correctly and storing it in the 'password' column in the table that im calling from the login script?

            That is not where your problem is.

            zijlstravideo pointed it out.

            In the code in your first post you have this line:

            if ($_POST['password'] === $password)

            You are comparing the unencrypted password that the user entered with the encrypted password from the database.

            They will never match.

            You need to encrypt the password entered to do the comparison.

            So the code he put up there should replace the if you are using:

            if (password_hash($_POST['password'], PASSWORD_BCRYPT) === $password)

            .
            All cookies cleared!

            Comment

            • Publisher Bucks
              Confirmed User
              • Oct 2018
              • 1330

              #7
              Originally posted by sarettah
              That is not where your problem is.

              zijlstravideo pointed it out.

              In the code in your first post you have this line:

              if ($_POST['password'] === $password)

              You are comparing the unencrypted password that the user entered with the encrypted password from the database.

              They will never match.

              You need to encrypt the password entered to do the comparison.

              So the code he put up there should replace the if you are using:

              if (password_hash($_POST['password'], PASSWORD_BCRYPT) === $password)

              .
              I've changed that line and still get the same incorrect user/pass error

              // Try and connect using the info above.
              $con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
              if ( mysqli_connect_errno() ) {

              exit('Failed to connect to MySQL: ' . mysqli_connect_error());
              }

              if ($stmt = $con->prepare('SELECT id, password FROM Register WHERE username = ?')) {
              $stmt->bind_param('s', $_POST['username']);
              $stmt->execute();
              if ($stmt->num_rows > 0) {
              $stmt->bind_result($id, $password);
              $stmt->fetch();
              if (password_hash($_POST['password'], PASSWORD_BCRYPT) === $password) {
              session_regenerate_id();
              $_SESSION['loggedin'] = TRUE;
              $_SESSION['name'] = $_POST['username'];
              $_SESSION['id'] = $id;
              echo 'Welcome ' . $_SESSION['name'] . '!';
              } else {
              // Wrong password
              echo 'Incorrect User/Pass!';
              }
              } else {
              // Wrong username
              echo 'Incorrect User/Pass!';
              }
              $stmt->store_result();
              $stmt->close();
              }
              Thats why i thought there may have been an issue elsewhere in the submit.php i posted above.
              Extreme Link List - v1.0

              Comment

              • sarettah
                see you later, I'm gone
                • Oct 2002
                • 14297

                #8
                Have you printed out what are in the 2 variables to see what you are comparing?

                Also, you are printing out the same error msg in 2 places. Change 1 of them so you know exactly which error you are hitting.

                .
                All cookies cleared!

                Comment

                • zijlstravideo
                  Confirmed User
                  • Sep 2013
                  • 806

                  #9
                  Originally posted by sarettah
                  Have you printed out what are in the 2 variables to see what you are comparing?

                  .
                  Yeah, this should be easy to debug. If PHP tells you the two variables don't match, they don't match.

                  Echo both your $_POST variable and $password, and see why they don't match.

                  EDIT:
                  On your signup form, you use $password = mysqli_real_escape_string($link, $_REQUEST['password']), before you hash it and store it into your database.
                  Therefore, any added slashes before escaped characters become part of the hash as well.
                  Perhaps try: if(password_hash(mysqli_real_escape_string($_POST['password']), PASSWORD_BCRYPT) === $password)
                  Contact: email

                  Comment

                  • k0nr4d
                    Confirmed User
                    • Aug 2006
                    • 9231

                    #10
                    His issue is very simple - he's using BCRYPT, which generates a different hash for the same string each time it's run. You can literally run it on the same password 100 times and get 100 different hashes. As such, you can't compare strings like you could with a normal salted MD5 or something.

                    You have to use this:
                    https://www.php.net/manual/en/functi...ord-verify.php

                    Code:
                    if(password_verify($_POST['password'], $password)) {
                    Mechanical Bunny Media
                    Mechbunny Tube Script | Mechbunny Webcam Aggregator Script | Custom Web Development

                    Comment

                    • zijlstravideo
                      Confirmed User
                      • Sep 2013
                      • 806

                      #11
                      Originally posted by k0nr4d
                      His issue is very simple - he's using BCRYPT, which generates a different hash for the same string each time it's run. You can literally run it on the same password 100 times and get 100 different hashes. As such, you can't compare strings like you could with a normal salted MD5 or something.
                      Haha, that explains a lot. The good old PHP docs to the rescue...
                      Contact: email

                      Comment

                      • Publisher Bucks
                        Confirmed User
                        • Oct 2018
                        • 1330

                        #12
                        Originally posted by sarettah
                        Have you printed out what are in the 2 variables to see what you are comparing?

                        Also, you are printing out the same error msg in 2 places. Change 1 of them so you know exactly which error you are hitting.

                        .
                        Good point, says inccorect username.
                        Extreme Link List - v1.0

                        Comment

                        • Publisher Bucks
                          Confirmed User
                          • Oct 2018
                          • 1330

                          #13
                          Originally posted by zijlstravideo
                          Yeah, this should be easy to debug. If PHP tells you the two variables don't match, they don't match.

                          Echo both your $_POST variable and $password, and see why they don't match.

                          EDIT:
                          On your signup form, you use $password = mysqli_real_escape_string($link, $_REQUEST['password']), before you hash it and store it into your database.
                          Therefore, any added slashes before escaped characters become part of the hash as well.
                          Perhaps try: if(password_hash(mysqli_real_escape_string($_POST['password']), PASSWORD_BCRYPT) === $password)
                          That doesnt seem to be working either :/
                          Extreme Link List - v1.0

                          Comment

                          • Publisher Bucks
                            Confirmed User
                            • Oct 2018
                            • 1330

                            #14
                            Originally posted by k0nr4d
                            His issue is very simple - he's using BCRYPT, which generates a different hash for the same string each time it's run. You can literally run it on the same password 100 times and get 100 different hashes. As such, you can't compare strings like you could with a normal salted MD5 or something.

                            You have to use this:
                            https://www.php.net/manual/en/functi...ord-verify.php

                            Code:
                            if(password_verify($_POST['password'], $password)) {
                            I'm still getting an error when using that K0nr4d.
                            Extreme Link List - v1.0

                            Comment

                            • Publisher Bucks
                              Confirmed User
                              • Oct 2018
                              • 1330

                              #15
                              Would it be best to change the encryption method at this point to something else or do you think I'll still run into the issue because of an existing coding issue?
                              Extreme Link List - v1.0

                              Comment

                              • k0nr4d
                                Confirmed User
                                • Aug 2006
                                • 9231

                                #16
                                Originally posted by Publisher Bucks
                                Would it be best to change the encryption method at this point to something else or do you think I'll still run into the issue because of an existing coding issue?
                                Yeah just do salted MD5.

                                columns username, password, and salt
                                salt you insert a random string when inserting the user so each one has a unique salt.

                                $salt = md5(uniqid());
                                $password = md5($_POST['password'].$salt);

                                and then you just go

                                $result = mysqli_query($dblink, "SELECT * FROM users WHERE username = '".$_POST['username']."' AND password = MD5(CONCAT('".$_POST['password']."',salt))");

                                (naturally, youd' protect against sql injection but just writing like that to illustrate what goes where).

                                If there's a result, the user is valid. If it's empty, it's wrong login details.
                                Mechanical Bunny Media
                                Mechbunny Tube Script | Mechbunny Webcam Aggregator Script | Custom Web Development

                                Comment

                                • zijlstravideo
                                  Confirmed User
                                  • Sep 2013
                                  • 806

                                  #17
                                  Originally posted by Publisher Bucks
                                  Would it be best to change the encryption method at this point to something else or do you think I'll still run into the issue because of an existing coding issue?
                                  Think you can still use it. leave your signup form as is (where you insert the hash into your db), then on your login form:

                                  replace: if ($_POST['password'] === $password)

                                  with:
                                  if(password_verify(mysqli_real_escape_string($_POS T['password']), $password))


                                  You've added slashes on your signup form, see this part of your code:
                                  $password = mysqli_real_escape_string($link, $_REQUEST['password']);
                                  // Securing password using password_hash
                                  $secure_pass = password_hash($password, PASSWORD_BCRYPT);
                                  So you need to add those again during login...

                                  Edit: k0nr4d already replied and yeah, md5 + salt would be easier.
                                  Contact: email

                                  Comment

                                  • Publisher Bucks
                                    Confirmed User
                                    • Oct 2018
                                    • 1330

                                    #18
                                    Originally posted by k0nr4d
                                    and then you just go

                                    $result = mysqli_query($dblink, "SELECT * FROM users WHERE username = '".$_POST['username']."' AND password = MD5(CONCAT('".$_POST['password']."',salt))");

                                    (naturally, youd' protect against sql injection but just writing like that to illustrate what goes where).

                                    If there's a result, the user is valid. If it's empty, it's wrong login details.
                                    So I have it inserting a salt value into the SQL table, but where do I put that part above? Does that replace the original line of code I have bolded below or is that a completely new line of code?

                                    <?php
                                    session_start();
                                    $DATABASE_HOST = 'localhost';
                                    $DATABASE_USER = 'user';
                                    $DATABASE_PASS = 'pass';
                                    $DATABASE_NAME = 'db';
                                    // Try and connect using the info above.
                                    $con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
                                    if ( mysqli_connect_errno() ) {

                                    exit('Failed to connect to MySQL: ' . mysqli_connect_error());
                                    }

                                    if ($stmt = $con->prepare('SELECT id, password FROM Register WHERE username = ?')) {
                                    $stmt->bind_param('s', $_POST['username']);
                                    $stmt->execute();
                                    if ($stmt->num_rows > 0) {
                                    $stmt->bind_result($id, $password);
                                    $stmt->fetch();
                                    if ($_POST['password'] === $password) {
                                    session_regenerate_id();
                                    $_SESSION['loggedin'] = TRUE;
                                    $_SESSION['name'] = $_POST['username'];
                                    $_SESSION['id'] = $id;
                                    echo 'Welcome ' . $_SESSION['name'] . '!';
                                    } else {
                                    // Wrong password
                                    echo 'Incorrect Password!';
                                    }
                                    } else {
                                    // Wrong username
                                    echo 'Incorrect Username!';
                                    }
                                    $stmt->store_result();
                                    $stmt->close();
                                    }
                                    ?>
                                    Sorry this whole password hashing stuff has me confused af
                                    Extreme Link List - v1.0

                                    Comment

                                    • Publisher Bucks
                                      Confirmed User
                                      • Oct 2018
                                      • 1330

                                      #19
                                      Oh and one other question, for the salt column, do I set that at varchar(255) or does it need to be longer/shorter?

                                      Its currently vachar(255).
                                      Extreme Link List - v1.0

                                      Comment

                                      • zijlstravideo
                                        Confirmed User
                                        • Sep 2013
                                        • 806

                                        #20
                                        Originally posted by Publisher Bucks
                                        Oh and one other question, for the salt column, do I set that at varchar(255) or does it need to be longer/shorter?

                                        Its currently vachar(255).
                                        You really need to check the PHP docs when you want to know something about a function.

                                        https://www.php.net/manual/en/function.uniqid

                                        "With an empty prefix, the returned string will be 13 characters long. If more_entropy is true, it will be 23 characters."


                                        https://www.php.net/manual/en/function.md5.php

                                        "Returns the hash as a 32-character hexadecimal number."
                                        Contact: email

                                        Comment

                                        Working...