Before I knew better, I implemented a login system with md5 as the hashing algorithm. Now that I do know better, I'd like to move to using PHPass. My problem is that the system is already in production and asking all users to change their passwords would be the mother of all headaches.
I've come up with a simple enough solution, but given my previous mistake I'd like to make sure I'm not making an equally grievous mistake due to ignorance.
My solution is as follows:
Change
md5($_POST['pass'])
To
md5($_POST['pass'])
$hasher->HashPassword()
$hasher->CheckPassword()
to check the re-hashed password against value from DBJust for clarity, I'm only re-hashing the md5 version because that's what I already have in the DB. It's not intended as an added security measure (although if it is, that's great!).
Although originally designed as a cryptographic message authentication code algorithm for use on the internet, MD5 hashing is no longer considered reliable for use as a cryptographic checksum because security experts have demonstrated techniques capable of easily producing MD5 collisions on commercial off-the-shelf ...
The MD5 message-digest algorithm is a cryptographically broken but still widely used hash function producing a 128-bit hash value. Although MD5 was initially designed to be used as a cryptographic hash function, it has been found to suffer from extensive vulnerabilities.
Salting MD5 isn't good enough. MD5 isn't collision-resistant, meaning an attacker can come up with a password to match any given hash value (whether or not it's actually the "right" password).
Unfortunately, MD5 has been cryptographically broken and considered insecure. For this reason, it should not be used for anything. Instead, developers should switch to the Secure Hash Algorithm or a Symmetric Cryptographic Algorithm.
MD5() problem is WAY exaggerated on this enthusiast programmers community site. Nothing actually bad in this hashing algorithm, especially in comparison with other parts of usual newbie application. Using phpass techniques on a usual PHP site is like using a safe lock on a paper door of a straw hut.
Most important thing in keeping passwords safe against virtual possibility of being stolen and used against the same user on other sites (oh, my!) is password strength and salt. Not hashing algorithm itself. No hashing technique would protect silly pass like "1234" or "joe".
So, md5 + strong password + average salt
is better than usual password + phpass
There is not a ingle reason to phpass existing md5 hash
A sensible migration algorithm is
The problem you're talking about isn't really specific to PHPass, but hashing passwords in general. It's basically just double-hashing. This topic has been talked about already in another question: Is "double hashing" a password less secure than just hashing it once?
If you have a look there, you can see that there is still debate over whether double hashing is worse, since it reduces the range of characters passed into the second (or subsequent) hashing function. However, it slows down the hashing process, combating brute force attacks, but only doing it twice won't act as much of a speed bump.
If you didn't want to have to deal with the double hashing, what you could try doing was adding a flag field to your users
database table, and set that to true
for all new users who join after you setup the new PHPass form of hashing. Then, when a user log in, if they don't have the flag field set, use the old hashing system, or the modified version you have detailed in your question. If they do have the flag field, you can use whatever new hashing process you have set up.
Update: Actually, building on that, what you could try is having that flag setup, and once they go to log in under the old system, if it is a match, then you'll still have their unhashed password in your $_POST
data, so you can then run that through your new hashing setup, save the new hash, then set the flag to true
, since they've been upgraded to the new hashing method. From then on, they'll be using the new hashing method.
You're getting some pretty dubious advice here, so you might want to ask on IT Security. Contrary to what some folks have said, the password hashing algorithm does matter; you want to use salting and a slow hash such as bcrypt, scrypt, or PBKDF2. See: Which password hashing method should I use?, Do any security experts recommend bcrypt for password storage?, How to securely hash passwords?, Most secure password hash algorithm(s)?. PHPass is a good library.
To migrate your users over to PHPass, you'll want to have two password hash databases: the old one (with MD5 hashes), and the new one (with PHPass hashes). Initially, the new one will be empty. When a user logs in, check whether you have an entry for them in your old password hash database (with MD5 hashes), and if you don't find an entry there, look in the new password hash database (with PHPass hashes). If you find an entry in the old database, you'll want to use MD5 to hash and check their password. If it is correct, you'll want to hash their cleartext password using PHPass, insert it into the new password hash database, and remove them from the old password hash database. If you don't find an entry in the old database, you can check for an entry in the new database and check the validity of their password with PHPass. Basically, you gradually migrate each user over from old-style to new-style hash when they next log in. Does this make sense?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With