My code is actually working but it\'s not at all secure, I don\'t want to use MD5 as it\'s not all that secure. I\'ve been looking up password hashing but I\'m not sure how I would incorporate it into my code.
Login:
require_once __DIR__.\'/config.php\';
session_start();
$dbh = new PDO(\'mysql:host=\' . DB_HOST . \';dbname=\' . DB_USERNAME, DB_USERNAME, DB_PASSWORD);
$sql = \"SELECT * FROM users WHERE username = :u AND password = :p\";
$query = $dbh->prepare($sql); // prepare
$params = array(\":u\" => $_POST[\'username\'], \":p\" => $_POST[\'password\']);
$query->execute($params); // execute
$results = $query->fetchAll(); // then fetch
//hash passwords pls
if (count($results) > 0 ){
$firstrow = $results[0];
$_SESSION[\'username\'] = $firstrow[\'username\'];
echo \"Hello $username you have successfully logged in\";
//header (\"location:.php\");
}
else{
echo \"Login Has Failed\";
return;
}
Register:
$dbh = new PDO(\'mysql:host=\' . DB_HOST . \';dbname=\' . DB_USERNAME, DB_USERNAME, DB_PASSWORD);
$username = $_POST[\"username\"];
$email = $_POST[\"email\"];
$password = $_POST[\"password\"];
$stmt = $dbh->prepare(\"insert into users set username=\'\".$username.\"\', email=\'\".$email.\"\', password=\'\".$password.\"\' \");
$stmt->execute();
echo \"<p>Thank you, you are registered</p>\";
Could anyone show me how to incorporate it into the code I have?
Just use a library. Seriously. They exist for a reason.
- PHP 5.5+: use
password_hash()
- PHP 5.3.7+: use
password-compat
(a compatibility pack for above)
- All others: use phpass
Don\'t do it yourself. If you\'re creating your own salt, YOU\'RE DOING IT WRONG. You should be using a library that handles that for you.
$dbh = new PDO(...);
$username = $_POST[\"username\"];
$email = $_POST[\"email\"];
$password = $_POST[\"password\"];
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $dbh->prepare(\"insert into users set username=?, email=?, password=?\");
$stmt->execute([$username, $email, $hash]);
And on login:
$sql = \"SELECT * FROM users WHERE username = ?\";
$stmt = $dbh->prepare($sql);
$result = $stmt->execute([$_POST[\'username\']]);
$users = $result->fetchAll();
if (isset($users[0]) {
if (password_verify($_POST[\'password\'], $users[0]->password) {
// valid login
} else {
// invalid password
}
} else {
// invalid username
}
About making your code more secure:
- You should ALWAYS validate user entries, even from a POST method which can be changed by using firebug before submitting the form. As you are inserting the user input in a query, it\'s much more important.
About your question in general
As I advised you in the comment, use PHPass or already made APIs which will do the job for you.
You\'ll hash the username, pass and salt at account creation time and insert the hash in the database.
At authentication time, you\'ll regenerate a hash with the given login + password input and the information you added to generate the salt.
If both generated hashes match, then the user is authenticated.
EDIT: Yes password_hash is good also.
Basically, you have two options, varying in complexity:
- Store a Hash of the registered user\'s password, using a hashing algorithm of your choice (more into this later).
- create a random salt (a constant, secret string) to be used together with the user\'s password, to create the hash as stated above and then store that hash in the DB.
When you retrieve the user record, you compare the hash computed from the provided password, with the hash stored in the DB.
Example:
$HashedPass = hash(\'sha512\', $password);
or with a pre-defined SALT:
$HashedPass = hash(\'sha512\', $password.SALT_STRING);
Store this into the DB as you did before.
Authenticating in done similarly:
$HashedPass = hash(\'sha512\', $password.SALT_STRING);
and then retrieve from the DB based on that hash comparison to the stored one.
Now, I\'d like to address your concerns about Hashing algorithms:
You dont have to use md5, you can as well use more secure hashing algorithms, refer to a comment here:
PHP\'s hash function
One suggestion is to use sha512 algorithm.
Most importantly, you should understand that hash is a one way conversion - there is no practical way to reverse engineer the original password from the hash alone, only perhaps finding alternative strings, which produce the same hash string.
I hope you find using a strong Hash algorithm, along with a Salt to mitigate the damage of a stolen Hash DB, good enough for your needs.