Calling back a crypted password? - php

I hashed my password into the database using the crypt() function.
$cryptpass = crypt($user_pass);
Now when i try to login in with my password that is "test" it wont work.
Here is the PHP from login
$user_name = mysql_real_escape_string($_POST['user_name']);
$user_pass = crypt($_POST['user_pass']);
$user_level = mysql_real_escape_string($_POST['user_level']);
$encrypt = md5($user_pass);
$admin_query = "select * from admin_login where user_name='$user_name' AND user_pass='$user_pass' AND user_level='$user_level'";
Sorry i am kinda new to password hashing , in the whole time i saved my passwords as plain texts.
EDIT: When i echo the query here are the results
crypt = $1$vh4.Mq4.$YaABh9aqRKbKpACTDApWb1 ,select * from admin_login where user_name='testcr' AND user_pass='$1$vh4.Mq4.$YaABh9aqRKbKpACTDApWb1' AND user_level='a' ,the real password is "test" .

You have choosen an extremely unsafe way to store the passwords (DES and MD5 hash without salting). You should think about using PHP's function password_hash(), to create a BCrypt hash.
For verification you will first have to get the hash from the database by username, afterwards you can verify the password with password_verify(). Directly verifying the hash with an SQL query is not possible because of the salt.
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
If you are interested to read more about this topic, have a look at my tutorial about safely storing passwords.

Try debugging your SQL statement.
$admin_query = "select * from admin_login where user_name='$user_name' AND user_pass='$user_pass' AND user_level='$user_level'";
echo $admin_query;
Run the query in your SQL engine and see if you can spot the differences.

Related

Migrate from SHA256 hashed passwords to BCRYPT in PHP7+MySQL

I have an old web application with a few users registered that is using the unsecure hash("sha256", trim($_POST["password"])) to store the hashed password in MySQL database. Now I want to update the web application to use the more secure BCRYPT password_hash() however I don't want to email all registered users alerting them to change their password. So I was thinking on implementing BCRYPT on the sha256() hashed password this way:
To save the password I will sha256() hash the user's password:
$hashed_password = password_hash(hash("sha256", trim($_POST["password"])), PASSWORD_BCRYPT);
Then I will save the BCRYPT hashed password in the database.
And to verify the user's password I would simply do this:
$hashed_password = "select hashed_password from users where email = 'abc#email.com'";
if(password_verify(hash("sha256", trim($_POST["password"])), $hashed_password))
{
echo "Welcome";
}
else
{
echo "Wrong Password!";
}
This way I will just update the user's password in the MYSQL database by looping each registered user, then I will retrieve the sha256() hashed password, and finally I will just re-save it after it has been BCRYPTed with password_hash():
$new_password = password_hash($old_sha256_hashed_password, PASSWORD_BCRYPT);
$mysql->save_user_password($new_password, $user_id);
So users will still be able to login with their old password.
What do you think about this solution?
Is it still safe even if I sha256() hash the password before BCRYPT it?
Since your current hashing system (unsalted SHA256) is indeed very unsecure, you could give immediate protection to the passwords with double hashing. As soon as possible, when the user logs in the next time, I would switch to the new algorithm and remove double hashing.
Make old hashes more secure:
$doubleHashToStoreInDb = password_hash($oldUnsaltedSha256HashFromDb, PASSWORD_DEFAULT);
Doing this for each row will protect the otherwise unsecurely stored passwords. Note the PASSWORD_DEFAULT parameter, it should be prefered over a specific algorithm, because it is future proof. And mark the double hashes, so you can distinguish between double hashes and already converted hashes, see why.
Handle new user registrations:
$hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT);
Just use the new algorithm without double hashing.
Verify logins:
if (checkIfDoubleHash($storedHash))
{
$correctPassword = password_verify(oldPasswordHash($_POST["password"]), $storedHash);
if ($correctPassword)
storeConvertedHash(password_hash($_POST['password'], PASSWORD_DEFAULT));
}
else
{
$correctPassword = password_verify($_POST['password'], $storedHash);
}
// Hashes the user password with a deprecated hashing scheme
function oldPasswordHash($password)
{
return hash("sha256", trim($password));
}
Double hashes will be converted to the new password hash function, this is possible because we have the original user password at this moment. New hashes are verified with password_verify() which is a future proof and backwards compatible function.
Adapting the password algorithm to future hardware is not a one-time task, it will be necessary as soon as new hardware will become faster. PHP offers the function password_needs_rehash() to find out whether a rehashing is necessary, then you can also calculate a new hash and store it.

how to create md5 password in php and save to database?

I have an existing database with users, each users password is stored as an MD5 hash.
Im trying to create a login form using PHP (Which im very new too) only I cant seem to get it to work, I know my username and password is correct yet I still receive the error that its wrong, Have I got to convert my password input to MD5 before checking the username in the table?
I currently have...
if (isset($_POST['register'])){
$name = $_POST['name'];
$username = $_POST['username'];
$password = $_POST['password'];
$confirm_password = $_POST['confirm_password'];
if ($password == $confirm_password) {
$query = mysqli_query($db, "INSERT INTO users (name, username, password) VALUES ('$name', '$username', MD5('".$password."'))");
//$query="INSERT INTO ptb_users (id,user_id,first_name,last_name,email )VALUES('NULL','NULL','".$firstname."','".$lastname."','".$email."',MD5('".$password."'))";
echo 'OK.';
} else {
echo 'Error.';
}
}
It is possible to use md5 as your encryption algorithm, but I would suggest to use better alternatives. Take a look here, this is the official php documentation. Just using the basic example on that page would be more secure than md5
$password = password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
Back to your question, yes, if the password is saved as an md5 hash into the database you have to convert the password in input with the md5 function and then check if your hash is valid.
Still, I encourage you to use password_hash() and password_verify().
The answer to this question is "don't". Storing passwords as MD5 hashes is dangerously insecure, and should not be done. Same thing with SHA1 hashes.
PHP has built-in password_hash and password_verify functions since PHP 5.5. These should be used whenever you need to store a password.

Password_verify doesn't check correctly

Big problem with password_verify.
In my db there is a column:
password: $2y$10$1k72g4qYgd4t5koC5hj8sOit3545GfO5EhaIwVRfIiA2/eC3Hnu5e ('b')
When I want to check in order that this password is equal the letter a it given my completely 2 different codes.My code:
$hash = password_hash('b', PASSWORD_DEFAULT);
$pass = getPassword($email);
echo $hash . ", " $pass;
and it gives me:
$2y$10$oJbeQqGSee.pLcBNxqRzUecoCGc9fin7IF.evDVanN1pjmtIINSD2,
$2y$10$1k72g4qYgd4t5koC5hj8sOit3545GfO5EhaIwVRfIiA2/eC3Hnu5e
Why there are different?
It's because when not specified by the user, password_hash will generate a random salt. Salt is a string that is appended to a password before hashing. Thanks to salts being random, two users with same password will still have different hashes in database.
Good summary of the topic can be found on the wikipedia
In order to verify that the password is correct, you shouldn't manually compare hashes, which may be different with each use of password_hash because of random salts, but rather use function password_verify
You should use password_hash() before inserting into your storage and then when you verify you should use password_verify()
$pass = getPassword($email);
$verify = password_verify('b', $pass);
if ($verify) {
// passwords match
}
else {
// passwords do not match
}
See: password-verify for more info

Comparing hash value of password in PHP

As part of learning php, I wanted to try a register and login page, however, the site I'm following for how to store a password uses MySQLI and I'm not using that:
Hashing the password
$password1 = 'hello123';
// A higher "cost" is more secure but consumes more processing power
$cost = 10;
// Create a random salt
$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
// Prefix information about the hash so PHP knows how to verify it later.
// "$2a$" Means we're using the Blowfish algorithm. The following two digits are the cost parameter.
$salt = sprintf("$2a$%02d$", $cost) . $salt;
// Value:
// $2a$10$eImiTXuWVxfM37uY4JANjQ==
// Hash the password with the salt
$hash = crypt($password1, $salt);
I'm stuck on retrieving the password however, here's the site's code for it:
$username = 'Admin';
$password = 'gf45_gdf#4hg';
$sth = $dbh->prepare('
SELECT
hash
FROM users
WHERE
username = :username
LIMIT 1
');
$sth->bindParam(':username', $username);
$sth->execute();
$user = $sth->fetch(PDO::FETCH_OBJ);
// Hashing the password with its hash as the salt returns the same hash
if ( crypt($password, $user->hash) === $user->hash ) {
// Ok!
}
From what I can see, he grabs the hash value of the password for the user in the DB and compares the password that was passed using the hash and check with the one in the DB.
I've been trying this but the result hash is never the same as the original one:
$pwdtocheck = 'hello123';
// no call do DB yet, doing this on the same page after hashing, the $hash is the same as above
$pwdhash = crypt($pwdtocheck, $hash);
// if I echo $pwdhash it's never exactly the same as the $hash.
if ( $pwdhash === $hash) {
echo "same pwd";
}
I cannot see the actual problem in your code, maybe your database field is smaller than 60 characters, or you are comparing different passwords. In every case there is an easier and safer way to hash passwords, just use the new functions password_hash() and password_verify(). There exists also a compatibility pack for earlier PHP versions.
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
EDIT:
I see now that you are using a salt when you compare the passwords. In your line:
$pwdhash = crypt($pwdtocheck, $hash);
the $hash variable has the salt prepended to it because crypt() will automatically do that for you. crypt() will extract the salt from the $hash because it knows the expected length of the salt based on the algorithm used. See the documentation.
I'll keep my original answer below for context and for those looking for a similar answer.
END EDIT
The password is not the same for you because you are using a salt when you originally hash the password to put in your database, but you are not salting the password later when you check against the database.
You should use the same salt string when you save the password as when you check the user's password on login. Usually, you will randomly generate the salt string for each password (as you are doing) and then save the salt string to the database along with the hashed password (either in the same column or its own column) so that you can use the same salt to check the user's password on login.
See https://crackstation.net/hashing-security.htm#salt for reference.
I can't access the article you're referencing but I imagine:
You need to check using the salt as the salt and not the hash.
crypt($pwdtocheck, $user->salt) == $user->hash
should work

How do I create and store md5 passwords in mysql

Probably a very newbie question but, Ive been reading around and have found some difficulty in understanding the creation and storage of passwords. From what i've read md5/hash passwords are the best ways to store them in a database. However, how would I go about creating those passwords in the first place?
So say I have a login page with user bob, and password bob123
- how will I
1. get bobs password into the database to begin with (hashed)
2. how do I retrive and confirm the hashed password?
Thanks
Edit 2017/11/09: Be sure to take a look at the answer from O Jones.
First off MD5 isn't the greatest hashing method you could use for this try sha256 or sha512
That said lets use hash('sha256') instead of md5() to represent the hashing part of the process.
When you first create a username and password you will hash the raw password with some salt (some random extra characters added to each password to make them longer/stronger).
Might look something like this coming in from the create user form:
$escapedName = mysql_real_escape_string($_POST['name']); # use whatever escaping function your db requires this is very important.
$escapedPW = mysql_real_escape_string($_POST['password']);
# generate a random salt to use for this account
$salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
$saltedPW = $escapedPW . $salt;
$hashedPW = hash('sha256', $saltedPW);
$query = "insert into user (name, password, salt) values ('$escapedName', '$hashedPW', '$salt'); ";
Then on login it'll look something like this:
$escapedName = mysql_real_escape_string($_POST['name']);
$escapedPW = mysql_real_escape_string($_POST['password']);
$saltQuery = "select salt from user where name = '$escapedName';";
$result = mysql_query($saltQuery);
# you'll want some error handling in production code :)
# see http://php.net/manual/en/function.mysql-query.php Example #2 for the general error handling template
$row = mysql_fetch_assoc($result);
$salt = $row['salt'];
$saltedPW = $escapedPW . $salt;
$hashedPW = hash('sha256', $saltedPW);
$query = "select * from user where name = '$escapedName' and password = '$hashedPW'; ";
# if nonzero query return then successful login
you have to reason in terms of hased password:
store the password as md5('bob123'); when bob is register to your app
$query = "INSERT INTO users (username,password) VALUES('bob','".md5('bob123')."');
then, when bob is logging-in:
$query = "SELECT * FROM users WHERE username = 'bob' AND password = '".md5('bob123')."';
obvioulsy use variables for username and password, these queries are generated by php and then you can execute them on mysql
Please don't use MD5 for password hashing. Such passwords can be cracked in milliseconds. You're sure to be pwned by cybercriminals.
PHP offers a high-quality and future proof password hashing subsystem based on a reliable random salt and multiple rounds of Rijndael / AES encryption.
When a user first provides a password you can hash it like this:
$pass = 'whatever the user typed in';
$hashed_password = password_hash( "secret pass phrase", PASSWORD_DEFAULT );
Then, store $hashed_password in a varchar(255) column in MySQL. Later, when the user wants to log in, you can retrieve the hashed password from MySQL and compare it to the password the user offered to log in.
$pass = 'whatever the user typed in';
$hashed_password = 'what you retrieved from MySQL for this user';
if ( password_verify ( $pass , $hashed_password )) {
/* future proof the password */
if ( password_needs_rehash($hashed_password , PASSWORD_DEFAULT)) {
/* recreate the hash */
$rehashed_password = password_hash($pass, PASSWORD_DEFAULT );
/* store the rehashed password in MySQL */
}
/* password verified, let the user in */
}
else {
/* password not verified, tell the intruder to get lost */
}
How does this future-proofing work? Future releases of PHP will adapt to match faster and easier to crack encryption. If it's necessary to rehash passwords to make them harder to crack, the future implementation of the password_needs_rehash() function will detect that.
Don't reinvent the flat tire. Use professionally designed and vetted open source code for security.
Insertion:
INSERT INTO ... VALUES ('bob', MD5('bobspassword'));
retrieval:
SELECT ... FROM ... WHERE ... AND password=md5('hopefullybobspassword');
is how'd you'd do it directly in the queries. However, if your MySQL has query logging enabled, then the passwords' plaintext will get written out to this log. So... you'd want to do the MD5 conversion in your script, and then insert that resulting hash into the query.
PHP has a method called md5 ;-) Just $password = md5($passToEncrypt);
If you are searching in a SQL u can use a MySQL Method MD5() too....
SELECT * FROM user WHERE Password='. md5($password) .'
or
SELECT * FROM ser WHERE Password=MD5('. $password .')
To insert it u can do it the same way.
Why don't you use the MySQL built in password hasher:
http://dev.mysql.com/doc/refman/5.1/en/password-hashing.html
mysql> SELECT PASSWORD('mypass');
+-------------------------------------------+
| PASSWORD('mypass') |
+-------------------------------------------+
| *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
+-------------------------------------------+
for comparison you could something like this:
select id from PassworTable where Userid='<userid>' and Password=PASSWORD('<password>')
and if it returns a value then the user is correct.
I'm not amazing at PHP, but I think this is what you do:
$password = md5($password)
and $password would be the $_POST['password'] or whatever
just get the hash by following line and store it into the database:
$encryptedValue = md5("YOUR STRING");
To increase security even more, You can have md5 encryption along with two different salt strings, one static salt defined in php file and then one more randomly generated unique salt for each password record.
Here is how you can generate salt, md5 string and store:
$unique_salt_string = hash('md5', microtime());
$password = hash('md5', $_POST['password'].'static_salt'.$unique_salt_string);
$query = "INSERT INTO users (username,password,salt) VALUES('bob','".$password."', '".$unique_salt_string."');
Now you have a static salt, which is valid for all your passwords, that is stored in the .php file. Then, at registration execution, you generate a unique hash for that specific password.
This all ends up with: two passwords that are spelled exactly the same, will have two different hashes. The unique hash is stored in the database along with the current id. If someone grab the database, they will have every single unique salt for every specific password. But what they don't have is your static salt, which make things a lot harder for every "hacker" out there.
This is how you check the validity of your password on login.php for example:
$user = //username input;
$db_query = mysql_query("SELECT salt FROM users WHERE username='$user'");
while($salt = mysql_fetch_array($db_query)) {
$password = hash('md5',$_POST['userpassword'].'static_salt'.$salt[salt]);
}
This method is very powerful and secure. If you want to use sha512 encryption, just to put that inside the hash function instead of md5 in above code.

Categories