Problems with password_hash() and password_verify() [duplicate] - php

This question already has answers here:
How to use PHP's password_hash to hash and verify passwords
(5 answers)
Closed 2 years ago.
Well I'm making a login system with MySQL and PHP. Then I want to crypt the user's password using password_hash and password_verify functions. But it isn't work for me at the time of compare the dehashed password with the hashed password (password_verify func).
So here is my code.
signup.php
$password_hashed = password_hash($data['password'], PASSWORD_DEFAULT, array("cost"=>15));
$statement = $connection->prepare("INSERT INTO users (username, email, password) VALUES (:username, :email, :password)");
if ($statement && empty($result1)) {
$result = $statement->execute( [
':username' => $data['username'],
':email' => $data['email'],
':password' => $password_hashed,
]);
header('Location: register.php');
$_SESSION['messages'][] = 'Thank you for registration. Check your email then log in.';
exit();
}
login.php
if ($user['username'] === $username && $user['password'] === password_verify($user['password'], $password)) {
header("Location: panel.php");
$_SESSION['username'] = $user['username'];
die();
} else {
$_SESSION['messages'][] = 'Incorrect user or password!';
header('Location: login.php');
}
Where $password: $password = $data['password'];
Where $user:
$statement = $connection->prepare('SELECT * FROM users WHERE username = :username');
$statement->execute([':username' => $username]);
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
$user = array_shift($result);
Output: Incorrect user or password!

This returns a boolean (true/false) value:
password_verify($user['password'], $password)
So this will never be true:
$user['password'] === password_verify($user['password'], $password)
Once you've selected the user from the database based on the provided username, just verify the password:
if (password_verify($user['password'], $password)) {
A couple notes on your terminology, becase it's important...
I want to crypt the user's password
No, you do not want to encrypt the user's password. You want to "hash" it. It's an important distinction. Encrypted things can be returned to their original form. Hashed things can not. Which is a vital part of password security.
compare the dehashed password with the hashed password
There's no "dehashed" anything. What the internals of password_verify does is hash the provided password and compare that result with the already-hashed stored password. At no point can you in any way convert the stored hashed password back to its original form.

Related

login using PHP data object [duplicate]

I'm using PHP's password hashing API to hash and verify my passwords on a site I'm building, however whenever I try and verify my password it always returns false.
I have a User class which sets the password before they are inserted into the database:
public function set__password($passwd) {
self::$password = password_hash($passwd, PASSWORD_BCRYPT, array('cost' => 12));
}
If the username and email is unique the new user row is inserted - upon checking my database I have what seems to be a valid BCRYPT string for my password:
$2y$12$lTMEP0wevDEMX0bzStzoyOEzOTIAi3Hyhd3nYjGwzbI
To verify my password, I run the following script:
$username = $_POST['username'];
$password = $_POST['password'];
$DB = Database::getInstance();
// Get the stored password hash
$res = $DB->run__query('SELECT password FROM users WHERE username = "' . $username . '"');
$hash = $res[0]['password'];
// Do the passwords match?
if(password_verify($password, $hash)) {
echo 'success';
} else {
echo 'failed';
}
$hash pertains to the string quoted above, however when I then call password_verify($password, $hash) where $password is the plain-text password retrieved from my input field, I always receive a value of false.
The given hash string example has 50 characters instead of 60. Double-Check the database - CHAR(60) - and var_dump($hash).
Other problem that you can have, is when you reduce the cost in the server for gaining time.
Always use password_hash($pass, PASSWORD_DEFAULT), is the best way.

PHP Log in page doesn't work with password_verify

So, I have hashed the password for new accounts which are created on adduser.php with this:
if (isset($_POST['submit'])) {
require "../functions/db-insert.php";
$productcategory = [
'username' => $_POST['username'],
'password' => sha1($_POST['password']),
'isadmin' => $_POST['isadmin']
];
//$hash = password_hash($_POST['password'], PASSWORD_DEFAULT);
$category = insert($pdo, 'users', $productcategory);
echo "<p>User added</p>";
}
and now I'm trying to modify my login.php to be able to sign properly using password_verify, but I seem to be doing something wrong as I can no longer sign in.
if (isset($_POST['submit'])) {
if (isset($_POST["username"]) && isset($_POST["password"])) {
$results = $pdo->prepare("SELECT * FROM users
WHERE username = :username AND password = :password");
$values = [
':username' => $_POST["username"],
':password' => $_POST['password']
];
$password = $_POST['password'];
$hash = password_hash($password, PASSWORD_DEFAULT);
$results->execute($values);
$row = $results->fetchAll();
if(count($row) < 1){
echo '<h3><strong>Wrong username or password!</h3>';
}
else if (!password_verify($password, $hash)){
$_SESSION['loggedin'] = true;
$_SESSION['name'] = $_POST['username'];
echo "<h3>Welcome back " . $_SESSION['name'] . " !</h3>";
}
}
}
At this point, I'm not entirely sure what I'm doing wrong and would really appreciate if someone could help me troubleshoot the stuff I do wrong. I've looked all over stackoverflow but none of the previously asked questions were working for me, unfortunately.
You're re-hashing the password. When you use password_hash you don't get the same value for the same string, so you are never going to find a match. You need to select the password (hashed) and then pass the raw string (input) into password_verify. So just have the username in the where, then use result password and the raw string in password_verify
Try echoing out a password_hash of the same value (e.g. password_hash('test'....). and you will see. You also need to account for using md5 is this is what you have done before. If this is a live system it will be difficult as you will basically need to make everyone change their password or write some routine to update it next time they log in (e.g. use the old verification method then password_hash() the password and update it). If this isn't production code yet just clear your your passwords and start again.
Also I just noticed you have said you want to log people in if the password verification returns false ,(!password_verify.... So your logic back to front

how to call encrypted Password PHP to Android Mysql

my login activity cannot read encrypted Password i tried without encrypted password and it works and im not sure if the error from php or activity itself of how to decryption password
im Using PASSWORD_BCRYPT
<?php
include "conn.php";
$Email = $_POST['Email'];
$Password = $_POST['Password'];
$sql_login = "SELECT * FROM users WHERE Email = :EMAIL and Password =:PASSWORD";
$stmt = $PDO->prepare($sql_login);
$stmt->bindParam(':EMAIL', $Email);
$stmt->bindParam(':PASSWORD', $Password);
$stmt->execute();
if ($stmt->rowCount() > 0) {
$returnApp = array('LOGIN' => 'SUCCESS');
echo json_encode($returnApp);
}else{
$returnApp = array( 'LOGIN' => 'FAILED');
echo json_encode($returnApp);
}
?>
To correctly use hashing of a password in PHP, use the password_hash and password_verify combination.
When a user signs up, you get his password, hash it and store it in the database:
$hash = password_hash($_POST['newpassword'], PASSWORD_DEFAULT);
// store $hash in database column "password"
When this user wants to login, you check against the hash:
// fetch hash from database, store it in $stored_hash
$logged_in = password_verify($_POST['password'], $stored_hash);
if ($logged_in === TRUE) {
echo "Welcome!";
} else {
echo "Username or password incorrect.";
}
Final notes:
Use PASSWORD_DEFAULT and make sure your database can store the result (also in the future). Hashing algorithms happen to get cracked once in a while.
You could use another provider like Google or Facebook to handle your authentication. This does have its drawbacks as well though.

Password changing code error

I am using password_hash function, it work's well in registration form and login form but doesn't work during change password form, it gives me error message incorrect old password may be my code has gone wrong or may be because password_hash generates different set of characters each time even with the same input, if it is so what method is used to update password. the same code works using md5.
if(isset($_POST['senddata'])){
$old_password = $_POST['oldpassword'];
$new_password = $_POST['newpassword'];
$repeat_password = $_POST['newpassword2'];
$query = $db->prepare("SELECT * FROM users WHERE username=:username");
$query->execute(array(':username'=>$username));
$row = $query->fetch(PDO::FETCH_ASSOC);
$db_password=$row['password'];
// hash old password before match
$old_password = password_hash($old_password, PASSWORD_DEFAULT);
// check if old password equals db_password
if ($old_password==$db_password) {
// continue changing users password
if ($new_password==$repeat_password) {
// hash the new password
$new_password=password_hash($new_password, PASSWORD_DEFAULT);
$repeat_password=password_hash($repeat_password, PASSWORD_DEFAULT);
// update password
$password_update_query=$db->prepare("UPDATE userss SET password=:password, password2=:password2 WHERE username=:username");
$password_update_query->execute(array(':password'=>$new_password,':password2'=>$repeat_password2,':username'=>$username));
echo "Your Password Updated";
}
} else {
echo "Old password is incorrect";
}
}
You need to use password_verify($password, $hash); for verifying that passwords are equal
When you hash it again you get a other result because it generates a new salt, which then result in an other hash.
Something like:
$old_password = $_POST['oldpassword'];
$db_password = $row['password']; // which should be already hashed
if (password_verify($old_password, $db_password) {

PHP SHA256 and Salt won't work

I'm trying to create passwords that are sha256 hashed with a $salt variable to it. But for some reason it just won't work. Been working 3 hours on this now, and I'm about to rip my head off. Here is my code:
I'll try again, sorry ;o)
Ok, my script worked fine, untill I tried to add the sha256 to the passwords. I got a file for creating users which is:
$salt = "lollol";
$password = hash('sha256', $salt.$_POST['password']);
$sql = ("INSERT INTO members (username, password, name, last_name,company)VALUES('$username', '$password', '$name', '$last_name', '$company')")or die(mysql_error());
if(mysql_query($sql))
echo "Your accuont has been created.";
It seems like it's correctly added to the Database. I can see that it is getting hashed with some letters and numbers.
But then when I'm trying to login, it just won't.
My code for login.php is:
$sql= "SELECT * FROM members WHERE username='$username' and password='$password'";
$result=mysql_query($sql);
$row=mysql_fetch_array($result);
$username = mysql_real_escape_string($_POST['username']);
$password = $_POST['password'];
$salt = "lollol";
$auth_user = hash('sha256', $salt.$password);
if($password == $salt.$auth_user){
echo "Logged in";
} else {
echo "Not logged in";
}
I got the idea of that, I have to encrypt password when I want to log in, but im not sure. I hope that some of you can help me.
When trying to login you concatenate the hash with the salt once more
$auth_user = hash('sha256', $salt.$password);
if($password == $salt.$auth_user){ // <-- $salt once more
echo "Logged in";
} else {
echo "Not logged in";
}
It should work, if you just remove it
$auth_user = hash('sha256', $salt.$password);
if($password == $auth_user){
echo "Logged in";
} else {
echo "Not logged in";
}
Update: Going further
here
$sql= "SELECT * FROM members WHERE username='$username' and password='$password'";
You try to retrieve the row, where the username matches $username and the password matches $password. In the database the passwords are already hashed (and $password seems to be not defined at all), thus this query will never return any row.
$password = hash('sha256', $salt.$_POST['password']);
$username = mysql_real_escape_string($_POST['username']);
$sql= "SELECT * FROM members WHERE username='$username' and password='$password'";
$result=mysql_query($sql);
$result should now contain the only user that matches the given credentials. Its now very easy
if (mysql_num_rows($result) === 1) {
echo "Logged in";
} else {
echo "Not logged in";
}
You're storing an encrypted password, but your select query is looking for the unencrypted password.
Just get the matching username (without a password condition) - usernames are unique, right?:
$sql= "SELECT * FROM members WHERE username='$username'";
$result=mysql_query($sql);
$row=mysql_fetch_array($result);
$username = mysql_real_escape_string($_POST['username']);
$password = $_POST['password'];
$salt = "lollol";
$auth_user = hash('sha256', $salt.$password);
if($row["password"] == $auth_user){
echo "Logged in";
} else {
echo "Not logged in";
}
$password = $_POST['password'];
// This should be the users actual salt after you've found the user
// in the database by username or email, or other means
$salt = $users_stored_salt;
// This should be the exact method you use to salt passwords on creation
// Consider creating a functon for it, you must use the same salt
// on creation and on validation
$hashed_password = hash('sha256', $salt.$password.$salt);
// This is the user's hashed password, as stored in the database
$stored_password = $users_stored_password;
// We compare the two strings, as they should be the same if given the
// same input and hashed the same way
if ($stored_password === $hashed_password){
echo "Logged in";
} else {
echo "Not logged in";
}
Missed your edit, but hope this helps.
EDIT: I see you aren't storing unique hashes.
If you are looking up the user by password, you need to hash the password in your query the same way it was stored:
$salt = $your_salt;
$hashed_password = hash('sha256', $salt.$_POST['password']);
$sql= "SELECT * FROM members WHERE username='$username' and password='$hashed_password'";
Otherwise, you could look up by unique username (not by password) and just compare the hashed input to the value of the stored password.
I'm very confused right now. How should my login_ac.php look like, if I should make it with the code I gave you in the top?
Just change the query to lookup by hashed password (the way you stored it).
$sql= "SELECT * FROM members WHERE username='$username' and password='".hash('sha256', $salt.$_POST['password'])."'";
You can remove the other validation and hashing - if you found the user then you know the input is valid.
Note that this only works when you know the way you're hashing the input is the exact same way you hashed the password upon creation.
It is worth checking that the field length in the database is big enough to store the whole hashed password without truncating it. You will never get a password match when logging in if the stored password is has the end missing.

Categories