Reputation: 27
I want a form where user can change password. I am able to encrypt a password, however when it is selected from the database(the original password say 'test') it does not recognise it.
This is when the password has been encrypted in db. i am checking to see if the typed password in form matches the one in the db:
SELECT * from table where password = md5('$typed_password')
This is how it is encrypted:
UPDATE table set field = md5('$typed_password' )
How can my select work so that when a user types it in the form the original one is recognied?
Upvotes: 2
Views: 1780
Reputation: 23749
firstly: MD5 is a cryptographic hash function, not necessarily an encryption method. A hash is designed to only be performed in one direction, and cannot be reversed. (this is a good thing)
MD5 is however cryptographically broken (not considered secure anymore); you should use another hash function (preferable Bcrypt-hash or at least SHA256)
Looking at the code, I can see several things wrong:
$typed_password
is properly sanitized or you are in for SQL-injection.The easiest (and probably best) way of doing passwords is by using a standard library: the Portable PHP password hashing framework and make sure you use the CRYPT_BLOWFISH
algorithm.
require('PasswordHash.php');
$pwdHasher = new PasswordHash(8, FALSE);
// $hash is what you would store in your database
$hash = $pwdHasher->HashPassword( $password );
// $hash would be the $hash stored in your database for this user
$checked = $pwdHasher->CheckPassword($password, $hash);
if ($checked) {
echo 'password correct';
} else {
echo 'wrong credentials';
}
the store/check/update queries should be bound to the user's Id:
// Insert query
$query = "INSERT INTO users VALUES({$userId}, '{$username}', '{$hash}')";
// Select query
$query = "SELECT hash FROM users WHERE userId = {$userId}";
// Update query
$query = "UPDATE users SET hash = '{$hash}' WHERE userId = {$userId}";
And then, you should use parametrised queries instead of directly passing the variable values into the query.
I realise this is a lot of info at once, but it is vital learn this if you do not want your script to be hackable by almost every programmer out there.
Upvotes: 4
Reputation: 5478
A recent post on passwords I got a little off topic and covered a lot of this. A tidbit:
Once you are happy with the password they have picked encrypt it with PHP first, then store. The following password encryption function is not my idea either, but solves a number of problems. Encrypting within PHP prevents people on a shared server from intercepting your unencrypted passwords. Adding something per user that won't change (I use email as this is the username for my sites) and add a hash (SALT is a short constant string I change per site) increases resistance to attacks. Because the SALT is located within the password, and the password can be any length, it becomes almost impossible to attack this with a rainbow table. Alternately it also means that people can't change their email and you can't change the SALT without invalidating everyone's password though.
function password_crypt($email,$toHash) {
$password = str_split($toHash,(strlen($toHash)/2)+1);
return hash('sha256', $email.$password[0].SALT.$password[1]);
}
So on first input of the user password, in pseudo code:
define(SALT,'blah');
$hashed_password = password_crypt($email,$password);
INSERT INTO users (email,hashed_password) VALUES ($email,$hashed_password);
Then to check a subsequent login in pseudo code:
define(SALT,'blah');
$user_hashed_password = password_crypt($_POST['username'],$_POST['password']);
SELECT email FROM users WHERE email = ? AND hashed_password = $user_hashed_password LIMIT 1
If you get a row back, valid login.
Upvotes: 0
Reputation: 9480
Why not encrypt the password in PHP and then INSERT
already encrypted one.
Same with SELECT
.
So:
$enc_passwd = md($typed_password);
$sql = "SELECT * FROM table WHERE password = '$enc_passwd')";
similar with UPDATE
(why not INSERT
?)
Upvotes: 1