I am having some problems getting password_verify to confirm my hashed password.
This is my login:
if (isset($_POST["login-button-front"]))
{
// IF VALUE IS GIVEN
if (isset($_POST["user-password"]) && ($_POST["user-email"])){
$user_email = $_POST["user-email"];
// QUERY DATABASE TO VERIFY LOGIN INFORMATION
$query_password = $db->prepare("SELECT password, user_session FROM login WHERE email = :user_email");
$query_password->execute(array(':user_email' => $user_email));
$password_row = $query_password->fetchAll();
// CHECK PASSWORD
$password = $_POST["user-password"];
$password_hash = $password_row[0]["password"];
if(password_verify($password, $password_hash)){
$_SESSION['user'] = $password_row['user_session'];
require 'members.php';
}
// RESPOND IF WRONG INFORMATION GIVEN
else{
$login_wrong = "The username and/or password you entered is incorrect. Please try again.";
require 'front_page.php';
}
}
// RESPOND IF NO INFORMATION GIVEN
else{
$login_wrong = "You must enter a valid username and password to login. Need an account? Register below.";
require 'front_page.php';
}
}
And this is my registration:
$password = password_hash($_POST['password1'], PASSWORD_DEFAULT);
I looked over all my details, removed single and double quotes. Aswell as made sure there was no fetching errors. This was my working code:
if (isset($_POST["login-button-front"]))
{
// IF VALUE IS GIVEN
if (isset($_POST["user-password"]) && ($_POST["user-email"])){
$user_email = $_POST["user-email"];
// QUERY DATABASE TO VERIFY LOGIN INFORMATION
$query_password = $db->prepare("SELECT password, user_session FROM login WHERE email = :user_email");
$query_password->execute(array(':user_email' => $user_email));
$password_row = $query_password->fetchAll();
// CHECK PASSWORD
$password = $_POST["user-password"];
$password_hash = $password_row[0]["password"];
if(password_verify($password, $password_hash)){
$_SESSION['user'] = $password_row[0]['user_session'];
require 'members.php';
}
// RESPOND IF WRONG INFORMATION GIVEN
else{
$login_wrong = "The username and/or password you entered is incorrect. Please try again.";
require 'front_page.php';
}
}
// RESPOND IF NO INFORMATION GIVEN
else{
$login_wrong = "You must enter a valid username and password to login. Need an account? Register below.";
require 'front_page.php';
}
}
I ended up hashing using this:
$password_options = ['cost' => 11,'salt' => mcrypt_create_iv(22,MCRYPT_DEV_URANDOM),];
$password = password_hash($_POST['password1'], PASSWORD_BCRYPT, $password_options);
Related
I am working on a Forgot-Password system where users are emailed a ForgotKey code to enter to access a reset password screen. When this ForgotKey is entered into the database, it is hashed. I used a similar system for my signup page and it's working correctly. I copied most of the code over from that system and now I am getting an error that the user's inputted password does not match the hashed password in the database. Am I using the correct password_verify code for this scenario?
$Email = $_SESSION['PWResetEmail'];
$ForgotKey = $_POST['ForgotKey'];
$ForgotKeySQL = "SELECT Email, ForgotKey, ForgotTime, UserID FROM UserTable WHERE Email = ?";
$ForgotKeySTMT = $conn->prepare($ForgotKeySQL);
$ForgotKeySTMT->bind_param("s", $Email);
$ForgotKeySTMT->execute();
$ForgotKeyRESULT = $ForgotKeySTMT->get_result(); // get the mysqli result
while ($ForgotKeyROW = $ForgotKeyRESULT->fetch_assoc()) {
// A: If password matches DO NOT hash, then send user back to forgot.php to retry
$ForgotKeyCheck = password_verify($ForgotKey, $ForgotKeyROW['ForgotKey']);
if ($ForgotKeyCheck == false) { // <----- code is failing here
$ForgotKeySTMT->free_result();
$ForgotKeySTMT->close();
header("Location: ../forgot.php?4");
exit();
}
// A: If password matches hash, then let user pass to next step of forgot password system.
else if ($ForgotKeyCheck == true) { // <---- I want this line to be true
$ForgotTimeFINAL = $ForgotKeyROW['ForgotTime'];
$UserIDTemp = $ForgotKeyROW['UserID'];
$_SESSION['UserIDTemp'] = $UserIDTemp;
$_SESSION['ForgotKey'] = $ForgotKeyROW['ForgotKey'];
$ForgotKeySTMT->free_result();
$ForgotKeySTMT->close();
header("Location: ../forgot.php?3");
exit();
}
else {
$ForgotKeySTMT->free_result();
$ForgotKeySTMT->close();
header("Location: ../forgot.php?2");
exit();
}
}
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.
I'm trying to has a password in PHP using password_hash and password_verify. I am correctly hashing the password as it is being into the database hashed, but when I attempt to unhash the password whilst logging in, it doesn't seem to want to work. The password is being recieved from an Android application but after echoing both the username and the password, they are correct to what they should be. To hash the password, I am using PASSWORD_DEFAULT as the hashing technique.
Code:
<?php
error_reporting(0);
require_once('dbconnect.php');
$username = $_POST["username"];
$password = $_POST["password"];
$result = $conn->query("SELECT * FROM User WHERE username ='$username'");
if(empty($result)){
die("Username doesn't exist");
}
$dbpass = $conn->query("SELECT password FROM User WHERE username = '$username'");
if (password_verify($password, $dbpass)){
$stmt = "SELECT * FROM User WHERE username='$username' and password='$password'";
$check = mysqli_fetch_array(mysqli_query($conn, $stmt));
if(isset($check)){
echo "success";
}else{
echo "Invalid Username or Password";
}
}
else {
echo "password not unhashing";
}
$conn->close();
Am I missing something obvious?
First, use prepared statements to remove the threat of SQL injection, or your login screen becomes an attack vector. Then the problem is you're not getting the actual dbpass, you're getting a result set containing $dbpass, without dereferencing it.
Try it this way:
//username in where clause is coming from the user, don't execute it
//also fetch a clean copy of the username from the database we can trust to do things with like display -- assuming we filtered it on the way into the database.
$stmnt = $conn->prepare('select username,password from user where username = ?') or die('...');
//username must be a string, and to keep it clear it came from a user, and we don't trust it, leave it in POST.
$stmnt->bind_param('s',$_POST['username']) or die('...');
//Do the query.
$stmnt->execute() or die('...');
//Where to put the results.
$stmnt->bind_result($username,$dbpass);
//Fetch the results
if($stmnt->fetch()) //get the result of the query.
{
if(password_verify($_POST['password'],$dbpass))
{
//The password matches.
}
else
{
//password doesn't match.
}
}
else
{
//username is wrong.
}
I'm trying to add Phpass to my website but no matter what I do I can't get the $check boolean to return true to let me actually log in, So far I've managed to encrypt my password with it and store it on the database but checking against it is failing.
<?php
if(isset($_POST['Login'])){
$EM = $_POST['Email'];
// Password from form input
$PW = $_POST["Password"];
// Passwords should never be longer than 72 characters to prevent DoS attacks
if (strlen($PW) > 72) { die("Password must be 72 characters or less"); }
// Just in case the hash isn't found
$stored_hash = "*";
// Retrieve the hash that you stored earlier
$stored_hash = "this is the hash we stored earlier";
// Check that the password is correct, returns a boolean
$check = $hasher->CheckPassword($PW, $stored_hash);
if ($check) {
// passwords matched! show account dashboard or something
$result = $con->query("select * from user where Email='$EM' AND Password='$PW'");
$row = $result->fetch_array(MYSQLI_BOTH);
session_start();
$_SESSION["UserID"] = $row['UserID'];
header('Location: Account.php');
} else {
// passwords didn't match, show an error
header('Location: Fail.php');
}
}
Because I've been trying to add to an existing login I wonder if I have excess code which is just breaking it? Or maybe I just messed it up all together as no matter what I try when logging in the only thing that will load is
header('Location: Fail.php');:|
Thanks in advance!
Edit: Right, I have a register file that saves the hashed password to the database:
if(isset($_POST['Register'])){
session_start();
$FName = $_POST['First_Name'];
$LName = $_POST['Last_Name'];
$Email = $_POST['Email'];
// In this case, the password is retrieved from a form input
$PW = $_POST["Password"];
// Passwords should never be longer than 72 characters to prevent DoS attacks
if (strlen($PW) > 72) { die("Password must be 72 characters or less"); }
// The $hash variable will contain the hash of the password
$hash = $hasher->HashPassword($PW);
if (strlen($hash) >= 20) {
// Store the hash somewhere such as a database
// The code for that is up to you as this tutorial only focuses on hashing passwords
$sql = $con->query("INSERT INTO user (Fname, Lname, Email, Password)Values('{$FName}','{$LName}', '{$Email}', '{$hash}')");
} else {
// something went wrong
}
echo $hash;
// $StorePassword = password_hash($PW, PASSWORD_BCRYPT, array('cost' => 10));
header('Location: Login.php'); //Redirect here when registering
And then I wish to read it from the database, compare it to the password entered etc.
How do I pull that info from the mysqli db to compare it? and hopefully make it work?
This is the tutorial I was following: https://sunnysingh.io/blog/secure-passwords
if(isset($_POST['Login'])){
$EM = $_POST['Email'];
// Password from form input
$PW = $_POST["Password"];
// Passwords should never be longer than 72 characters to prevent DoS attacks
if (strlen($PW) > 72) { die("Password must be 72 characters or less"); }
$result = $con->query("select * from user where Email='$EM'");
$row = $result->fetch_array(MYSQLI_BOTH);
if ($row) {
// Check that the password is correct, returns a boolean
$check = $hasher->CheckPassword($PW, $row['Password']);
if ($check) {
// passwords matched! show account dashboard or something
session_start();
$_SESSION["UserID"] = $row['UserID'];
header('Location: Account.php');
exit;
}
}
// passwords didn't match, show an error
header('Location: Fail.php');
}
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) {