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.
Related
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) {
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'";
I am fairly new to php security, and for my site, I was a sign up and login, and I want to add md5 their passwords, but I can't find anywhere which has a clear guide on what needs to be added to the sign up, and what needs to be added to the login files, and/or the database, as I say I am fairly new to php in terms of web security, so I am in need of some help, here's part of what I have on my sign up form:
$error = $user = $pass = "";
if (isset($_SESSION['user'])) destroySession();
if (isset($_POST['user']))
{
$user = sanitizeString($_POST['user']);
$pass = sanitizeString($_POST['pass']);
if ($user == "" || $pass == "")
{
$error = "Not all fields were entered<br /><br />";
}
else
{
$query = "SELECT * FROM members WHERE user='$user'";
if (mysql_num_rows(queryMysql($query)))
{
$error = "Username already taken<br /><br />";
}
else
{
$query = "INSERT INTO members VALUES('$user', '$pass')";
queryMysql($query);
die("<h4>Account created</h4>Please Log in.");
}
}
}
I just need an example or a good guide of what I need to do to get it working correctly.
I think you're looking to salt and then hash your passwords. Simply add a string of your choosing to the front (and if you wish, to the end) of your password before hashing it using MD5.
e.g.
$pass = 'mypassword';
$salt = 'S%gh3578'; //anything you want
$pepper = 'w890rrk'; //anything you want
$query = "INSERT INTO members VALUES('$user', md5('".$salt.$pass.$pepper."'))";
queryMysql($query);
This will store the password in the database using salted MD5 encryption that cannot be reversed using a lookup table of common passwords using unsalted MD5 encryption.
To check if a password is valid, you do something similar:
$passToCheck = 'something';
$correctMD5 = (retrieve hash from db)
if($salt.$passToCheck.$pepper == $correctMD5)
{
//valid login
} else {
//login failure
}
You can for example md5($pass) before you insert and when the user logs in, you md5 again and check that the values are the same. There is no way to de-md5, so you will usually check the md5 input against the md5 DB value.