Migrate old md5 passwords to bcrypt passwords

Solution:

Oleksi and josnidhin did a great job at answering your question. I just wanted to add some ideas what to do during the transition phase:

Migrate the DB towards having two "password hash" columns, one containing the existing old MD5 hashes, and another one for the new bcrypt hashes, initially all filled with NULL. The next time a user logs in, you do these steps:

1) Check if there's already a value in the bcrypt column. If so continue with 3., otherwise with 2.

2) Authenticate the user with the old MD5 mechanism using the value from the MD5 column. If successful, additionally compute the new bcrypt hash and store it in the new column. Done.

3) Authenticate the user using the brypt value. Simply ignore the MD5 value.

Then from time to time, check whether the new bcrypt column is filled. If so, discard the MD5 column and update your app to only use the new mechanism.

But that's wishful thinking, there are always some users that haven't logged in in the meantime. Send them a mail telling them what you are doing, that it's for their best and ask them kindly to log in soon.

After a couple of weeks, check the bcrypt status again. If there's still some passwords missing (there will be :)), what you could do is to just reset the passwords of these users, generate a random one and informing them via mail, much like what you would do if they forgot their passwords.

Then, you can finally purge the MD5 column, discard the corresponding code and upgrade your app to only use the new authentication.


I have an alternative solution:

  1. Add bcrypt column.
  2. Populate bcrypt column by running MD5 hash through bcrypt algorithm.
  3. Change login to always use bcrypt column and hashing function that is plain text->md5->bcrypt.

This way all passwords can be migrated at once and MD5 hashes discarded permanently. Considering doing this myself, can't pick any faults with this idea. Any takers? Am I missing something obvious?


There is no way to convert an md5 hash into another kind of hash. You will have to make users log in using the old system, and then hash the password they give using the new method. Once you have the new hash, you can delete the old, md5 hash.