I 'm newbie to php and I 'm implementing a login system where user enters email and password and check for their existence in database (mysql in phpmyadmin)
the password is encrypted using this function when user first registers :
/**
* Encrypting password
*
* @param
* password
* returns salt and encrypted password
*/
public function hashSSHA($password) {
$salt = sha1 ( rand () );
$salt = substr ( $salt, 0, 10 );
$encrypted = base64_encode ( sha1 ( $password . $salt, true ) . $salt );
$hash = array (
"salt" => $salt,
"encrypted" => $encrypted
);
return $hash;
}
the salt parameter which is the key to decrypt the password is stored in the database with user's info and the decrypt code is :
/**
* Decrypting password
*
* @param
* salt, password
* returns hash string
*/
public function checkhashSSHA($salt, $password) {
$hash = base64_encode ( sha1 ( $password . $salt, true ) . $salt );
return $hash;
}
the password is decrypted when i go and fetch the user with the email and password entered.
/**
* Get user by email and password
*/
public function getUserByEmailAndPassword($email, $password) {
$stmt = $this->conn->prepare ( "SELECT * FROM users WHERE email = ?" );
$stmt->bind_param ( "s", $email );
if ($stmt->execute ()) {
$user = $stmt->get_result ()->fetch_assoc ();
$stmt->close ();
$salt = $user ["salt"];
$hash = $this->checkhashSSHA ( $salt, $user ["encrypted_password"] );
if ($hash == $password) {
return $user;
} else {
return NULL;
}
} else {
return NULL;
}
}
the problem is when user enters correct email and password still this code returns NULL and i suspect something wrong with handling the password part.
Siguza's answer is correct, but your comment to his answer reflects a very reasonable confusion, because the name of the checkhashSSHA()
function is a bit misleading (ie its name does not match its behaviour). A function name that start with "check" should be returning a boolean. I suggest changing it to:
/**
* Decrypting password
*
* @param
* password, hash, salt
* returns boolean
*/
public function checkhashSSHA($password, $hash, $salt) {
$hash2 = base64_encode ( sha1 ( $password . $salt, true ) . $salt );
return ($hash == $hash2) ;
}
Now change these two lines:
$hash = $this->checkhashSSHA ( $salt, $user ["encrypted_password"] );
if ($hash == $password) {
to this one line:
if (checkhashSSHA($password, $user["encrypted_password"], $salt)) {
Now it's clearer and easier to use, and its behaviour matches its name. However, if you care to enhance the naming in your code, here are some suggestions:
checkhashSSHA()
to compareHashSSHA()
. encrypted_password
in the database to hashed_password
. More importantly, the sha1 hashing algorithm is a bit old and not very secure. I recommend changing it to a more secure hashing like sha512. Check this and read the comment from Kai Petzke for the full story.
The problem lies in these two lines:
$hash = $this->checkhashSSHA ( $salt, $user ["encrypted_password"] );
if ($hash == $password) {
First, you're hashing the already hashed password, instead of the plaintext password.
Then you're comparing that "hash of a hash" to the plaintext password.
So you're doing hash(hash(pw)) == pw
, when it should be hash(pw) == hash(pw)
.
You simply have to exchange $user ["encrypted_password"]
and $password
:
$hash = $this->checkhashSSHA ( $salt, $password );
if ($hash == $user ["encrypted_password"]) {
I would suggest instead of using the sshhash function you look into the php function password_verify()
Check the docs on that and related functions here: http://php.net/manual/en/function.password-verify.php
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.