I am trying to set up a secure login & register system using crypt() as I have read that that is php's stored function for bcrypt
I am registering a user but taking their password and and then crypting it.
$hashed_password = crypt($mypassword);
I then store $hashed_password in the db
then when the user logs in I am trying to match the password to whats stored.
I found this function on php.net but cant get it to work
$password is the stored crypted password and $mypassword is the users input
if ($password == crypt($mypassword, $password)) {
echo "Success! Valid password";
}
I understand that crypt generates a unique hash each time its called so I dont understand how the function can work.
Am I completeley missing the point as I read that crypt() is a one function and decrypt does not exist?
any help greatly appreciated in not only showing the error of my ways but also in completing this secure login
You're using second parameter in your crypt() call, so it's treated as salt. To compare properly, you can use:
if ($password == crypt($mypassword))
{
echo "Success! Valid password";
}
But PHP provides native functionality for hashing routines - it is introduced if 5.5 version and called password hashing.
For PHP versions below 5.5 down to 5.3.7, there is a backported compatibility function that does the same: https://github.com/ircmaxell/password_compat Just include it and use it.
But note that you have to read the hashed password from the database and then compare it with PHP. You cannot query the database with a newly created password hash to find the user.
Assuming that the encrypted password from the database is $db_pass and the entered password is $new_pass. Then here's how you test it:
if($db_pass === crypt($new_pass)){
echo "Success!";
}
This post will help...
Assuming the current database is reading the password, all we have to do is:
} elseif (crypt($pass, $row['pass']) == $row['pass']) {
There are few steps you need here..this tutorial will help however:
http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL
Essentially you want to have the password encrypted in the database - eg. so if the password as 'mypassword' it would be stored in some random string like '3ifdgk5ty=-dlsfs'.
Read up on sha1 (md5 is no longer considered secure). Never used crypt myself however sha1() seems to do the job for me when used in conjunction with a salt (an additional text string added to the password to make it harder to break hack)
You can not decrypt it, because hash is one way. So you can not obtain the original input via hash. You can not reveal users passwords even if you have access to the database.
It is being used like this:
user writes password into input -> submits form -> password goes into database like following:
sha1($_POST['password']);
then you store this hashed password in database.
Whenever user wants to log in, he submits form again and it does this logic ($result['password']) comes from the database query:
if(sha1($_POST['password']) == $result['password']) {
//password match, so lets log you -> set sessions, cookies and so on
}
Related
I am just a little confused as to where I can fit it in this file. The file is for pw validation currently but I would like the pw to be hashed using password_hash. That being said I understand how password hashing works and more confused on how to properly implement it into my case. I've found many examples of creating a pw and hashing it but need help pulling pw from db and hashing it and updating the db. After I have that I can just use something along the lines of
if( password_verify($userpassword,hash)){
do something }
Or am I looking at this the wrong way and need to take a different approach. I fairly new to php and it is not my strong suite any help or info would be great.
You need to write a single, separate script to run one time to update all the plaintext passwords to those generated by password_hash().
Something like:
// FOR UPDATE locks the rows
$res = $dbh->query('SELECT id, password FROM users FOR UPDATE;');
$update = $dbh->prepare('UPDATE users SET password = ? WHERE id = ?;');
foreach($res->fetch_all() as $row) {
// https://www.php.net/manual/en/function.password-needs-rehash
if( password_needs_rehash($row['password'], PASSWORD_DEFAULT) {
$hash = password_hash($row['password'], PASSWORD_DEFAULT);
$update->bind_param('ss', $hash, $row['id']);
$update->execute();
}
}
Usually you might implement password_needs_rehash() into a login workflow to upgrade hashes on-the-fly, but if you have everything in plaintext you don't have to wait for the login to happen, and you absolutely need to get those all hashed ASAP.
I have a list of 100 users and their passwords stored in a database.
I need to update the passwords using a salt as within the UPDATE query, md5(name.salt).
What can be done and how?
for example :
user Password Salt
(1001 abc "nnmm000ajdsl")
(1002 def "nnjj000kdjsf")
I need to write a script to update the table by using md5 algo such that all password entries are changed to md5(user.salt)
what should i code?
I'd recommend having a look at the password_needs_rehash (http://php.net/password_needs_rehash) and password_hash (http://php.net/password_hash) functions.
If you still have plain text passwords, I recommend you write a script to hash all the passwords using password_hash and change your login code to check using it as well.
If you already have a weak hashing mechanism in place (like MD5), then you might want to either:
a) Rehash the password on login (using password_needs_rehash to check):
if (password_needs_rehash($hash, PASSWORD_BCRYPT)) {
$hash = password_hash($password, PASSWORD_BCRYPT);
// Store $hash in the database to replace the old hash
}
This means non-frequent visitors (or even old visitors who no longer return will have an old hash for a password.
or b) Write a script to hash your existing hashes again (this is generally accepted as an OK practice):
// Script that loops through each user
foreach ($users as $user) {
$hash = password_hash($user['hash'], PASSWORD_BCRYPT);
// Store $hash in the database to replace the old hash
}
Then in your login script do this:
$password = old_hash_function($password);
// $stored_hash_in_database contains the value in the database for the username specified
if (password_verify($password, $stored_hash_in_database)) {
// Log user in
}
You only have to do this once so speed is not een issue. SELECT the password and id, then hash it with something safe (not md5, it's to old). Then UPDATE it into the database.
Something like this:
$q = mysql_query("SELECT id, pass FROM table");
$r = mysql_fetch_assoc($q);
$pass = md5('salt' . $r['pass']);
myqsl_query("UPDATE table SET pass = $pass WHERE id = {$r['id']}");
UPDATE users SET password = md5(CONCAT(password, 'yoursalt'));
But it's better to keep passwords hashed by native PHP function password_hash, like Naktibalda answered before.
Don't use md5(), it is weak and insecure,
use a password_hash function instead http://uk1.php.net/password_hash
I am trying to create a login system and hence I encrypted password during registration with the password_hash($password,PASSWORD_BCRYPT) function. However I am having difficulties while comparing the login password provided by the user with the bcrypted password stored in the database.
Here is the code without the security functions I tried while trying to compare the login password with the registered password. Any help would be greatly appreciated.
$loginpassword=$_POST['password'];
$con=mysqli_connect($ip,$username,$dbpass,$dbname);
$regpassword="SELECT password FROM customerdb WHERE username='$username'";
$result=mysqli_query($con,$regpassword);
$value=mysqli_fetch_fields($result);
if(password_verify($loginpassword,$value))
{
session_start();
header(.........);
exit();
}
P.S. I am using php 5.4. Hence I included the password_compat from https://github.com/ircmaxell/password_compat
The mysqli_fetch_fields method returns an array of metadata about the columns in the database, and not the values.
To get the password value, use mysqli_fetch_array. You also need to check a row was returned from the database.
$row = mysqli_fetch_array($result, MYSQLI_NUM);
if ($row) {
$value = $row[0];
// Verify...
} else {
// Invalid username
}
You should read up on SQL injection because your query is vulnerable to attack.
I am using php pdo at my user log in process with mysql ate database. I have tried bCrypt library for password encryption. But I am confused about how to check the input password with the encrypted one?
Here is my attempted code:
$bcrypt = new Bcrypt(15);
$hash = $bcrypt->hash($password);
$isGood = $bcrypt->verify($password, $hash);
$login = new UserManager();
$getuserInfo = $login -> checkLogin($username, $password);
foreach ($getuserInfo as $userInfo) :
if ($userInfo -> getUID() == $username) {
if($userInfo -> getPassword() == $password) ?
}
endforeach;
First, don't. Use an existing password library. Secure handling of password is very hard to do properly, and you'll almost certainly get it wrong.
Second: You can't compare the passwords this way ($userInfo->getPassword() == $password). Assuming you've stored the hashed password (it's really not obvious from the meager code you've posted) then you need to hash $password, and compare the hashed value against the stored hash. That's the whole point of password hashing: The hash produces the same output from the same input, so on account creation you store the irreversible output of hashing the password, and then on login you hash the newly submitted password and compare the result against the stored hash.
I am doing a security audit on my login logic and trying to figure out which password check is more secure, and the better algorithm. Below are the two methods in pseudo PHP code:
Method I:
$bcrypt = new Bcrypt();
$password_hash = $bcrypt->hash($_POST['password']);
$result = mysqli_query_check_login($username, $password_hash);
if(mysqli_numb_rows($result) > 0) {
//is valid
}
Method II:
$bcrypt = new Bcrypt();
$result = mysqli_query_check_login($username);
//Note $result->password is a bcrypt hash
if($bcrypt->verify($_POST['password'], $result->password)) {
//is valid
}
The difference is method I runs bcrypt hash and then sends the username and hashed password in the mysql query. Method II gets the hashed password from mysql via the username only and then in PHP compares the two values.
Is there any security difference?
Thanks.
These are effectively the same thing. There should be no security implications in using either method.
Method II would probably make it simpler to get the user's information and update something like a "failed login attempts" counter. Most implementations I've seen for Method I simply rely on WHERE user=$login AND password=$password not selecting the user if the password doesn't match.