I have a LAMP (PHP) website which is becoming popular.
I played it safe by storing the user passwords as md5 hashes.
But I now see that\'s not secure; I should h
You can migrate the passwords by adding a column in your tables to store the new format.
When a user logs in successfully, if the new column is empty, put the stronger password in there and empty out the original column. If the new column has an entry, compare the input to the value in there.
Why not add a new column new_pwd
to your user table, which stores the result of md5($originallyHashOfPwd . $salt)
. You can then precompute new_pwd
and once that's done adjust your login checking to compare the result of md5(md5($entered_pwd) . $salt)
to what's in new_pwd
. Once you're done switching your login checking, delete the old column.
That should stop rainbow-table style attacks.
sadly, your only way is to tell your users to renew their passwords.
you could also generate random passwords, but that is the same hassle.
edit
you could just double encode your stored passwords. so your new salted hashing algorithm would be:
md5(md5($new_password).$salt).':'.$salt
to update your old passwords use
md5($old_password.$salt).':'.$salt
to check if a provided password is correct simply use
list($stored_password, $salt) = explode(':', $salted_password);
if(md5(md5($provided_password).$salt) == $stored_password) {
// you are now logged in
}
You can do a "2 step hashing" instead of creating a hash in a single step.
You could append each password hash to the username, and then hash it again. This will create an undecryptable hash thats salted with unique informations.
The usual process of salting is
salt+PWD -> hash
You could do something like: PWD -> Hash -> UserID+Hash -> Hash
(Note the UserID was only picked so a unique salt for each double hash exists... Feel free to make your salt more complex)
You can still use a salt. Just calculate another hash from the current hash together with a salt:
$newHash = md5($salt.$oldHash);
For new passwords you then need to use:
$hash = md5($salt.md5($password));
Two options here
As far as I can see, there is no other way of recovering the passwords.
EDIT: Although MD5 is a hash and should not be decodable, it can be broken using rainbow tables: with probability almost one, you can find a unique (here's the probability) string of at most, say, 20 characters with a given hash, especially if your character set is limited, say, to alphanumeric. Strictly speaking, this is not decoding. For all practical purposes, it is. Extra note: producing the rainbow tables, and looking up 1000 password is still going to take a lot of time.