I write the following loginCheck code and the database schema I use is as follows:
userinfo:
username varchar
password varchar
code:
<?php
//set the MIME type to application/json
//header("Content-Type: application/json");
//get the username and password
$username = $_POST['username'];
$password = $_POST['password'];
//require database operation
require 'database.php';
$stmt = $mysqli->prepare ("SELECT username, password, COUNT(*) FROM userinfo WHERE username=?");
if(!$stmt){
echo json_encode(array(
"success" => false,
"message" => "an error occured, please try again"
));
exit;
}
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->bind_result($returnedUsername, $hashedPassword, $count);
$stmt->fetch();
if ($count==1 && crypt($password, $hashedPassword) == $hashedPassword) {
//all information provided is correct, start a session
ini_set("session.cookie_httponly", 1);
session_start();
$previous_ua = #$_SESSION['useragent'];
$current_ua = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['username'] = $username;
if(isset($_SESSION['useragent']) && $previous_ua !== $current_ua){
die("Session hijack detected");
} else{
$_SESSION['useragent'] = $current_ua;
}
//create a token
$_SESSION['token'] = substr(md5(rand()), 0, 10);
echo json_encode(array(
"success" => true,
"token" => htmlentities($_SESSION['token']),
"username" => htmlentities($_SESSION['username'])
));
exit;
} else {
echo json_encode(array(
"success" => false,
"message" => "Incorrect Username or Password"
));
exit;
}
$stmt->close();
?>
The url is:
http://ec2-54-148-227-9.us-west-2.compute.amazonaws.com/~beibeixhb/Calendar/calendar.php
I am not sure why it prevent me from logging in, any suggestions?
You are using the hashed version of your password as a salt to the password entered and you expect that to be the same as the hashed password. I don't think this can ever happen.
crypt($password, $hashedPassword) == $hashedPassword
It's not clear from your code where you get the salt from, but if you didn't use salt to hash the password to start with, taking out that second argument of crypt should do the job for you.
Alternatively, use the right salt as a second argument to crypt.
Related
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.
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 use crypt() function for protect password when i create user in database, but when i try to make a authentification system for connect my user, i don't understand how is work.
With this code, this always pass into the if "WRONG ID OR PASSWORD" :
<?php
//connexion to database
include'connexionBDD.php';
// Check connection
if ($bdd->connect_error) {
die("Connection failed: " . $bdd->connect_error);
}
echo "Connected successfully (".$bdd->host_info.")";
$pseudonyme = $_POST['pseudo'];
$password= $_POST['mdp'];
//on crypte le mot de passe
$password= crypt($password);
$req = $bdd->prepare('SELECT ID_utilisateur FROM utilisateurs
WHERE Pseudonyme = :pseudo AND Mot_de_passe = :mdp');
$req->execute(array(
'pseudo' => $pseudonyme,
'mdp' => $password));
$result= $req->fetch();
if(!$result)
{
echo "WRONG ID OR PASSWORD";
}
else
{
session_start();
$_SESSION['ID_utilisateur'] = $resultat['ID_utilisateur'];
$_SESSION['Pseudonyme'] = $pseudonyme;
$pseudo = $_SESSION['Pseudonyme'];
echo "<p> You are connected with $pseudo !<p></div>";
}
?>
crypt() as of now is not preferred way to store passwords.
Use password_hash() to generate password and password_verify() to compare them.
Example code:
$password = "tere";
$cryptPassword = password_hash($password, PASSWORD_DEFAULT);
$verify = password_verify($password, $cryptPassword);
var_dump($verify); // Returns bool(true)
Also crypt() is well documented in PHP Manual, read about that.
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);
I've made encrypting of the password in my register script and they are stored in the database, and I have to use them to login, so I would want to use the unencrypted ones to login. I've read some of the threads in here but nothing is helping me. How can I add it in my login.php? The salt is also stored in the database.
This is my register.php script for encrypting
$hash = hash('sha256', $password1);
function createSalt()
{
$text = md5(uniqid(rand(), TRUE));
return substr($text, 0, 3);
}
$salt = createSalt();
$password = hash('sha256', $salt . $hash);
and this is my login.php with season
//Create query
$qry="SELECT * FROM member WHERE username='$username' AND password='$password'";
$result=mysql_query($qry);
//Check whether the query was successful or not
if($result) {
if(mysql_num_rows($result) > 0) {
//Login Successful
session_regenerate_id();
$member = mysql_fetch_assoc($result);
$_SESSION['SESS_MEMBER_ID'] = $member['id'];
$_SESSION['SESS_FIRST_NAME'] = $member['username'];
$_SESSION['SESS_LAST_NAME'] = $member['password'];
session_write_close();
header("location: profile.php");
exit();
}
else {
//Login failed
//error message
}
else {
die("Query failed");
}
These examples are from php.net. Thanks to you, I also just learned about the new php hashing functions.
Read the php documentation to find out about the possibilities and best practices:
http://www.php.net/manual/en/function.password-hash.php
Save a password hash:
$options = [
'cost' => 11,
];
// Get the password from post
$passwordFromPost = $_POST['password'];
$hash = password_hash($passwordFromPost, PASSWORD_BCRYPT, $options);
// Now insert it (with login or whatever) into your database, use mysqli or pdo!
Get the password hash:
// Get the password from the database and compare it to a variable (for example post)
$passwordFromPost = $_POST['password'];
$hashedPasswordFromDB = ...;
if (password_verify($passwordFromPost, $hashedPasswordFromDB)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
According to php.net the Salt option has been deprecated as of PHP 7.0.0, so you should use the salt that is generated by default and is far more simpler
Example for store the password:
$hashPassword = password_hash("password", PASSWORD_BCRYPT);
Example to verify the password:
$passwordCorrect = password_verify("password", $hashPassword);
array hash_algos(void)
echo hash('sha384', 'Message to be hashed'.'salt');
Here is a link to reference http://php.net/manual/en/function.hash.php
You couldn't login because you did't get proper solt text at login time.
There are two options, first is define static salt, second is if you want create dynamic salt than you have to store the salt somewhere (means in database) with associate with user.
Than you concatenate user solt+password_hash string now with this you fire query with username in your database table.
I think #Flo254 chained $salt to $password1and stored them to $hashed variable. $hashed variable goes inside INSERT query with $salt.
You can't do that because you can not know the salt at a precise time. Below, a code who works in theory (not tested for the syntaxe)
<?php
$password1 = $_POST['password'];
$salt = 'hello_1m_#_SaLT';
$hashed = hash('sha256', $password1 . $salt);
?>
When you insert :
$qry="INSERT INTO member VALUES('$username', '$hashed')";
And for retrieving user :
$qry="SELECT * FROM member WHERE username='$username' AND password='$hashed'";