im doing a tutorial about how to make a php mysql login form.
now the tutorial is actualy made to good and i wold like to alter it a bit and change the login password to store cleartext instead of the hash. the hash line looks like this:
$new_password = password_hash($upass, PASSWORD_DEFAULT);
i made:
$new_password = $upass;
out of it. and it now saves the cleartext to the database but the login doesn't work.
the login part looks like this and i don't see the part where i expect the hashed-password to be converted and matched...
public function doLogin($uname,$upass)
{
try
{
$stmt = $this->conn->prepare("SELECT user_id, user_name, user_pass FROM users WHERE user_name=:uname");
$stmt->execute(array(':uname'=>$uname));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() == 1)
{
if(password_verify($upass, $userRow['user_pass']))
{
$_SESSION['user_session'] = $userRow['user_id'];
return true;
}
else
{
return false;
}
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
The line:
if(password_verify($upass, $userRow['user_pass']))
Checks the hash of the password against the given password. As you've removed the hashing function it's comparing an un-hashed password against a clear text password.
Change it to:
if($upass == $userRow['user_pass'])
That should fix it.
Although you really should not be storing clear text passwords.
If you're not hashing the passwords anymore then you can't verify the hash
if(password_verify($upass, $userRow['user_pass']))
Should be
if($upass == $userRow['user_pass'])
Understand that this is a very bad idea. You might not understand why hashing passwords is important
For any reason, your database may be compromised and its data may be obtained by someone else. If the passwords are in what we call plain text, you will have leaked a piece of sensitive information that your users have trusted you with: their password (which is very likely to be a password shared in multiple services). This is a very serious issue.
Related
This question already has answers here:
How to verify_password from a database
(2 answers)
Closed 3 years ago.
So I have a login page which worked fine without hashed passwords but of course, that wasn't secure so I decided to hash the passwords when registering.
but I don't know how and where should I use verify_password when I'm selecting the password from the database. I use while to see if there is a result with the username and password entered like this:
$q = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$x = $conn->query($q);
if ($x->num_rows > 0) {
while ($row = $x->fetch_assoc()) {
//Logged in seccesfully!
}
} else {
// Username or password is wrong!
}
password_hash() function can simplify our lives and our code can be secure. When you need to hash a password, just feed it to the function and it will return the hash which you can store in your database.
$hash = password_hash($password, PASSWORD_DEFAULT);
Now that you have seen how to generate hashes with the new API, let’s see how to verify a password. Remember that you store the hashes in a database, but it’s the plain password that you get when a user logs in.
The password_verify() function takes a plain password and the hashed string as its two arguments. It returns true if the hash matches the specified password.
<?php
if (password_verify($password, $hash)) {
// Success!
}
else {
// Invalid credentials
}
for more info read
I am using sha1 for my password security. I have stored password in this way in register.php
// secure password
$salt = openssl_random_pseudo_bytes(20);
$secured_password = sha1($password . $salt);
//Send it to mysql table
$result = $access->registerUser($username, $secured_password, $salt, $email, $fullname);
This all is working fine.
Problem is here:
In my login.php
$password = htmlentities($_POST["password"]);
$secure_password = $user["password"];
$salt = $user["salt"];
// 4.2 Check if entered passwords match with password from database
if ($secure_password == sha1($password . $salt)) {
//do something
} else {
//do something
}
I am always getting as password does not match.
where am I going wrong?
First is first. NEVER USE SHA OR MCRYPT TO STORE YOUR PASSWORD.
EDIT : The password_hash() function generates a long password hash, so make sure that your column in the mysql is a VARCHAR of 500 space
All these useless practises is the root reason why almost many websites get hacked. To tackle the situation, php did a lot of research and then at last came with the most secure function called the password_hash(). I am not more onto explaining about password_hash() here as there are already many documents on the internet.
You can always hash a password like this
<?php
$securePassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
$query = $db->query('INSERT INTO users ......');
?>
And, to verify the password, you can simply use this function
<?php
$passwordHash = $query['password']; //Password from database
$userPassword = $_POST['password']; //Password from form
if(password_verify($userPassword, $passwordHash)) {
echo 'Password is correct, logged in!';
} else {
echo 'Password is wrong, try again';
}
?>
And, answer for your question.
PLEASE DON'T USE SHA OR MCRYPT OR BCRYPT. IF YOU WANNA GET YOUR WEBSITE HACKED, THEN CONTINUE. OR USE password_hash()
The reason you don't get the hash genereated each time because the openssl_random_pseudo_bytes() generates random numbers each time. So each time, during execution, the function returns different numbers and you get your sha result wrong and thus giving a FALSE alert.
PLEASE, AGAIN. I BEG YOU TO USE password_hash() FUNCTION
For more information on password_hash() and password_verify() :
http://php.net/manual/en/function.password-hash.php
http://php.net/manual/en/function.password-verify.php
I am Using PHP version 5.4 and I have looked around for a while now for a hashing mecanism but I can't get it to work. The tricky part is validating the hashed password with another one the user tries, what am I doing wrong here?
//and yes I am using password as name in this example
$password_entered ="cucumberball";
$password_hash = crypt($password_entered);
mysql_set_charset('utf8');
pdoConnect();
//insert hashed pass (same name and pass(hashed) for user)
$stmt = $pdo->prepare("insert into user (name,password) values (:name,:password)");
$stmt->bindParam(':name', $password_entered);
$stmt->bindParam(':password', $password_hash);
$stmt->execute();
//retriving password from db and checking if its correct with the login password provided
$stmt = $pdo->prepare("select password from user where name = :name LIMIT 1;");
$stmt->bindParam(':name', $password_entered);
$stmt->execute();
$user = $stmt->fetch(PDO::FETCH_OBJ);
if(crypt($password_entered, $password_hash) == $user->password) {
// password is correct
echo "WORKS";
}else{
echo "did not work";
}
When you're comparing you are salting when encrypting the password and the password from the database is only encrypted.
if(crypt($password_entered, $password_hash) == $user->password) {
Also, according to the documentation you should be comparing like this
You should pass the entire results of crypt() as the salt for
comparing a password, to avoid problems when different hashing
algorithms are used. (As it says above, standard DES-based password
hashing uses a 2-character salt, but MD5-based hashing uses 12.)
if (hash_equals($hashed_password, crypt($user_input, $hashed_password))) {
echo "Password verified!";
Fix this if statement:
if(hash_equals(crypt($password_entered, $password_hash), $password_hash))
{
echo "WORKS";
}
Or as there is no hash_equals in PHP 5.4:
if(crypt($password_entered, $password_hash) == $password_hash)
{
echo "WORKS";
}
But without hash_equals, your hashes are vulnerable to timing attack.
Also you may want to read this manual.
This question already has answers here:
How to reverse SHA1 Encrypted text [duplicate]
(3 answers)
Closed 9 years ago.
I don't think that my title is appropriate for my question.
My question is I have a simle login system just for test purposes, and I am using sha1 in encrypting my password into my database. which would look like this
sha1($_POST['..some_variable...'])
What would be the best way to retrieve my encrypted password as plain text for authentication purposes.
Like select my username and password from my database.
This should give you a good idea of how it works.
try {
$submittedEmail = !empty($_GET['email']) ? $_GET['email']: false;
$submittedHash = !empty($_GET['password']) ? hash('sha1', $_GET['password']): false;
if (!$submittedEmail || !$submittedHash) {
throw new \Exception('Required field(s) missing. Please try again.');
}
if ($stmt = $mysqli->prepare("SELECT hash FROM user WHERE email = ?")) {
$stmt->bind_param("s", $submittedEmail);
$stmt->execute();
$stmt->bind_result($storedHash);
$stmt->fetch();
$stmt->close();
}
if (!$submittedHash != $storedHash) {
throw new \Exception('Wrong credentials submitted. Please try again.');
}
echo 'User ok!';
} catch (Exception $e) {
echo $e->getMessage();
}
I would however recommend using PHPs password_verify
Since you probably aren't on PHP 5.5 yet you can use this class
When the user creates an account and/or password the first thing you need to do is create a random salt.
$salt = hash_hmac('sha512', "RandomStringHere", "EncryptionKeyHere");
You will store that salt in db along with their encrypted password. From there encrypt the text-based password to and store it in the db.
$encyptPassword = hash_hmac('sha512', "plainTextPassword" . $salt , "EncryptionKeyHere");
So now you have a salt and encrypted password associated with the user.
To authenticate it's as easy as getting the salt associated with the user, taking their un-encrypted password and encrypting it - seeing if it matches.
This way you never know the persons password, just if it matches when they try to log in.
I am creating a login form. I am learning how to use SHA-1 to encrypt passwords. I used SHA-1 to encrypt the password that the user created during registration. In the database I inputted pretend username and password data, to have something to work with. I'm having problems getting my login form to work.
// Database Connection
$con = getConnection();
$sqlQuery = mysql_query("SELECT count(*) from Customers
WHERE Email = '$email' and Password = sha1('$passLogin')")
// Executing query
$result = $con->mysql_result($sqlQuery, "0");
if ($result == 0) {
echo "Can not login, try again.";
} else {
echo "Login Good!";
}
I am learning how to use sha1 to
encrypt passwords.
... use sha1 to hash passwords. Hashing is different from encryption. Encryption is reversible, hashing isn't. (or shouldn't be). Now, ...
You have to make sure the passwords in the database are hashed.
Usually you do the hashing on the PHP side.
You should use salting to make rainbow table attacks unfeasible. Read Just Hashing is Far from Enough for Storing Password
That said, I would do the authentication part like this:
$hashedAndSalted = sha1($passLogin . $yourSalt);
$sqlQuery = mysql_query("SELECT Email FROM Customers WHERE Email = '$email' AND Password = '$hashedAndSalted'");
if (mysql_num_rows($sqlQuery) == 1) {
echo 'Login successful';
} else {
echo 'Could not login';
}
Replace your query with this:
$sqlQuery = mysql_query("SELECT count(*) from Customers
WHERE Email = '".$email."' and Password = '".sha1($passLogin)."'");
Remember to always concatenate strings and variables manually, don't rely on PHP to do it for you. Also, you forgot the semicolon ; after that line. Every line must be appended with a semicolon in PHP.
On a separate note if you have not sanitized your form inputs you are wide open for SQL injection.
If user enters the following for Email field:
' or '1'='1
They will be logged in :)
You should be using mysql_real_escape_string to escape $email and $passLogin or even better use prepared statements.