Search code examples
ruby-on-rails-3hashdevisemd5password-hash

Migrate old md5 passwords to bcrypt passwords


I'm reworking a website in Rails using Devise for authentication. The previous website works with a database of users with md5 passwords, and therefore I want to migrate this passwords to the encryption that Devise using. How do I solve it?


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.