Password hash not work properly in my script.
Here my integration:
register.php
$password = password_hash(md5(sha1($_POST['password']) . $salt), PASSWORD_DEFAULT);
And here how i verify it:
Login.php
$password = md5(sha1($_POST['password']) . $salt);
$check = $mysqli->query("SELECT password FROM accounts WHERE email = '$email'");
$passw_hash = $check->fetch_assoc();
if (password_verify($password, $passw_hash["password"])) {
// LOGIN SUCCESSFULLY
}
My PHP version: 5.5
Or if you have any other method to encrypt password let me know.
UPDATE
1- Modified password's column size to VARCHAR (250) from VARCHAR (60)
2- Removed all other encryptions like md5, sha1, and cleaning the code to protect password against sql injections.
Example of hashed password:
Pure TEXT: google
Hashed: $2y$10$0Bd5Uv09Jg50QZZ4Iz7F2.WGV3MpYkScg9vuTONWmUCMYPJ3qDukC
I insert a new member to my database with prepared statements using mysqli:
$st = $mysqli->prepare("
INSERT INTO
accounts(
username,
password,
date
) VALUES (
?,
?,
?
)");
$st->bind_param('sss', $username, $password, $date);
$st->execute();
Since you're using password_hash() you do not want to use any additional hashing, so remove the md5() and sha1() functions.
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
Furthermore, remove the functions from your login:
$password = $_POST['password'];
By adding the other functions you're destroying the elements password_hash() and password_verify() need to do their jobs. Adding the two additional hashing mechanisms also don't make the hash any more secure.
Make sure you don't escape passwords or use any other cleansing mechanism on them before hashing. Doing so changes the password and causes unnecessary additional coding.
In addition Little Bobby says your script is at risk for SQL Injection Attacks. Learn about prepared statements for MySQLi. Even escaping the string is not safe! Don't believe it?
Related
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.
I have a login.php file using pdo for my website. For all my other queries up to this point based on user input, I've been using prepared statements, to protect against sql injection. However, for the login section, I'm comparing the inputted password against the hashed value in my database using password_verify(). I can't really use a prepared statement for this as my code looks like this:
if($res->fetchColumn() == 1){
$stmt2 = $conn->prepare("SELECT `password` FROM members WHERE :email = `email`");
$stmt2->bindParam(':email', $email);
$res2 = $stmt2->execute();
$passhash = $res2->fetchColumn();
$password_verify($_POST[password], $passhash);
//^^ do i need to sanitize that?
}else{
//login failed
}
This seems like it will be a simple answer, but I just want to make sure I'm doing it right.
you don't need to sanitize it as you are going to compare it with the hashed password from the database
plus on register.php you don't need to sanitize the password as you going to hash it using password_hash()
then save it to the database which won't cause any harm because it's already hashed
any sanitize to the password on register may spoil it
for example if the user used password like mypassword'1'2'3 after sanitize it will be
mypassword\'1\'2\'3 which is not the same
hope it helps
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.
I'm using PHP's crypt function for password hashing/encryption, but I don't think I am doing it right because "nathan12" and "nathan123" both allow me to login to my account on my system (the actual password is "nathan123", and therefore "nathan12" or anything else should NOT allow me to login).
Here's what my system does when a user registers:
[...]
$salt = uniqid(mt_rand(), true);
$password = crypt($password, $salt); // '$password' is the inputted password
$insertUserStmt = $mysqli->prepare("INSERT INTO users (name,
username,
password,
password_salt,
email,
created) VALUES (?, ?, ?, ?, ?, ?)");
$insertUserStmt->bind_param("sssssi", $name, $username, $password, $salt, $email, time());
$insertUserStmt->execute();
[...]
It inserts the hashed/encrypted password ($password) into the database along with the $salt.
When someone tries to login, the following is done to check if the user has inputted the correct password for the username they inputted:
[...]
// $password_salt is from DB; $password is inputted password
$password_crypt = crypt($password, $password_salt);
// $login_password is from DB
if($password_crypt == $login_password) {
[...]
I'm probably not even using the crypt function properly, but according to the PHP docs the first parameter is a string (the password) and second is the salt.
The standard DES-based crypt() [...] only uses the first eight characters of str, so longer strings that start with the same eight characters will generate the same result (when the same salt is used).
source
Use a salt that starts with $<algo>$ to use something other than DES. See the crypt() documentation for details.
You should be using password_hash() instead of crypt, for the reasons you mention: "I'm probably not even using the crypt function properly". You say you are getting the salt from the DB... this sounds insecure. with password_hash() you can let PHP handle the salting for you in a secure manner.
More details on why this is superior:
http://www.sitepoint.com/hashing-passwords-php-5-5-password-hashing-api/
You should use more than just a password salt to encrypt passwords.
You can store a random string in your configuration file.
$config['passwordKey'] = 'asjdfa783#H$Khjsdfhas78a734J%JSDGK2348235hxmfdA';
And append it to $salt when encrypting. This way if the database is compromised, and your file system is not, then attackers can't decrypt your database password hashes. This should be essential to protect the users information on other sites with identical login information.
To hash your passwords, password_hash is a simple crypt() wrapper specially configured for password hashing!
(source)
$password = password_hash($password, PASSWORD_BCRYPT, array(
'cost' => 60,
'salt' => $salt . $config['passwordKey']
));
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.