0

I have created two files - secured registration and secured login using hashing in PHP and using MySQL. Everything appears to be working. However, when I login, it doesn't appear to be working for some reason. I cannot pinpoint the underlying issue in secured password. What am I missing in the code somewhere?

Registration:

$firstname = trim($_POST["firstname"]);
$lastname = trim($_POST["lastname"]);
$emailaddress = trim($_POST["emailAddress"]);
$username = trim($_POST["username"]);
$password = trim($_POST["password"]);
$confirmpwd = trim($_POST["confirmpwd"]);

if ($password != $confirmpwd)
{
    header('Location: CreateNewAccount.php');
}

if (strlen($username) > 30)
{
    header('Location: CreateNewAccount.php');
}

$hash = hash('sha256', $password);

function createSalt() {
    $text = md5(uniqid(rand(), true));
    return substr($text, 0, 3);
}

$salt = createSalt();
$pwd = hash('sha256', $salt . $hash);

$conn = new PDO('mysql:host=localhost;dbname=database', 'root', '');

$query = $conn->prepare('INSERT INTO Member (firstName, lastName, email, username, password, salt) VALUES (?, ?, ?, ?, ?, ?)');
$query->execute(array($firstname, $lastname, $emailaddress, $username, $pwd, $salt));

header('Location: Login.php');

Login:

$username = $_POST['username'];
$password = $_POST['password'];

$conn = new PDO('mysql:host=localhost;dbname=database', 'root', '');

$query = "SELECT password, salt"
    . "FROM Member"
    . "WHERE username = :username";

$result = $conn->prepare($query);
$result->bindParam(":username", $username);
$result->execute();

$number_of_rows = $result->rowCount();

if($number_of_rows == 0) // User not found. So, redirect to Login.php
{
    header('Location: Login.php');
}

$userData = $result->fetch(PDO::FETCH_ASSOC);
$hash = hash('sha256', $userData['salt'] . hash('sha256', $password));

if($hash != $userData['password']) // Incorrect password. So, redirect to Login.php
{
    header('Location: Login.php');
} else // Redirect to Log Entry page
{
    header('Location: LogEntry.php');
}

Thanks for your help.

Marc
  • 67
  • 1
  • 10
  • 2
    Hi, would be nice if you could more clearly say what is not working. Btw I recommend taking a look at `password_hash` and `password_verify` it handels the hashing and salting for you. – Roland Starke Oct 08 '17 at 05:54
  • When I try to log in using the password I entered. It didn't allow me to log in at all. That's what's not working, I'm not sure why the login detected the password as an error but it's the correct one. – Marc Oct 08 '17 at 06:03
  • You don't have a space between `Member` and `WHERE` ->`... "FROM Member" . "WHERE ...` so this results in `FROM MemberWHERE`. Add a space after `Member` or before `WHERE` – Sean Oct 08 '17 at 06:04
  • Why you don't use MD5 to hash the password and insert into database, then query the username and password using query – Ali Oct 08 '17 at 06:04
  • Don't ever use md5 to hash passwords. That's the worst idea ever! Use php password hash and password verify. – Rotimi Oct 08 '17 at 06:07
  • @BarakatAliForoz MD5 is outdated, similar to dial up internet - [Secure hash and salt for PHP passwords](https://stackoverflow.com/questions/401656/secure-hash-and-salt-for-php-passwords) – Sean Oct 08 '17 at 06:07
  • Please follow same procedure in login that you used in register $pwd = hash('sha256', $salt . $hash); store the hashed password in separate variable and then hash it with salt – Ali Oct 08 '17 at 06:08
  • Its look like your query does not execute because of not having spaces, that returns `num_rows = 0`. Try like this `$query = "SELECT password, salt FROM Member WHERE username = :username";`. – Mofiqul Islam Oct 08 '17 at 06:12
  • Can you change your condition to this: if($hash == $userData['password']) { header('Location: LogEntry.php'); } else { header('Location: Login.php'); } – Ali Oct 08 '17 at 06:13
  • Tried using password_hash and password_verify but getting the same error. I think I'm missing somewhere. – Marc Oct 08 '17 at 06:23
  • ok now this is strange - I removed the hashing to test unsecured password and it appears to be working for some reason. Now I'm going to try and test against password_hash and password_verify. For some reason, when login, the test was unsuccessful the first time in earlier attempts. Furthermore, there are some false positive as well. – Marc Oct 08 '17 at 06:56

2 Answers2

0

1) As @Mofiqul Islam has state in his comment above, your SQL string in your login code ($query) is missing mandatory spaces, e.g. between salt and FROM and between Member and WHERE.

So the code you have shown can't be the real code because this would fail as soon as preparing the statement, and this does not seem to be your problem.

2) In your login code, you have to build the hash the same way as in your registration code. In your login code, replace the line

$hash = hash('sha256', $userData['salt'] . hash('sha256', $password));

by the following:

$hash = hash('sha256', $userData['salt'] . $password);

It should work then.

Nevertheless, as some comments have stated, don't try to do your own thing when it comes to password hashing. Instead, use PHP's modern functions password_xxx.

Binarus
  • 4,005
  • 3
  • 25
  • 41
  • Thanks - when I decided to use the PHP's modern functions, everything appeared to be working. Yet, there are few kinks to be fixed. I believe I missed somewhere in the code. – Marc Oct 08 '17 at 07:55
0

Apparently, this is one of the strangest approach to this. I may have discovered an issue. I had a domain class to store the data which might have caused the problem. After skipping the use of class and used the file to do all the work, everything appeared to be working so far.

But I cannot rule it out because this is only my assumption.

Marc
  • 67
  • 1
  • 10