Question

I've got a rails 3 production app that uses devise to deal with authentication. I'd like to change to using bcrypt instead of sha on the app but I can't find any resources that explain the process of migrating from one to the other. I am assuming that you will need to have some sort of fallback in place to handle the fact that the passwords at the moment are salted a certain way with sha...

Anyone done this before?! Any tips, tutorials, walk-throughs, etc?!

Was it helpful?

Solution

I don't think there is a solution you would like. I only know of two options -

reset all user passwords and email them telling them this has been done (and preferably why so they don't freak out)

as every user logs in, check against the old hash system you had, if it validates, create a new bcrypt hash in a new column and then remove the old, less secure hash and begin a slow migration that way.

The mathemtical power needed to create a rainbow table to move over everyone just isn't likely.

OTHER TIPS

Here's a better algorithm for ya, that will let you switch everyone over at once. You'll have to figure out how to implement this in devise, but here's the outline. This isn't mine, found on the web at the URL noted.


http://blog.jgc.org/2012/06/one-way-to-fix-your-rubbish-password.html

  1. Suppose you have a database that contains password hashes for the n users of your site, and for each user you have salt si and hash hi (where hi was computed with some algorithm such as SHA1 or MD5). (Note that the rest of these instructions work if there's no salt, just ignore it).

  2. Suppose that you've chosen to use scrypt. For each user you first create a new random salt value s'i and then compute a new hash h'i using the formula scrypt(s'i, hi) and store the new salt and hash in the database. You throw away the old weak hash hi and forget it ever existed. So you are left with two salt values and a new hash. (I've ignored the other scrypt parameters which are left to the reader to determine).

  3. When user i logs in and presents password p you use your old weak hash algorithm (let's suppose it was md5(salt, password)) to compute a hash for comparison as follows: scrypt(s'i, md5(si, p)) and compare that with the h'i stored in the database.

  4. If, like last.fm, you were also allowing third-parties to authorize users by presenting the old hash value instead of the password then you can still use this scheme. When the third-party presents hash h for user i you calculate scrypt(s'i, h) and do the comparison.

  5. If step 4 is not needed then you can go further when a user logs in. Once the user has logged in successfully with password p you can completely eliminate any trace of the old weak hash by choosing a new random salt value s''i and computing scrypt(s''i, p) and storing that in the database.

This has the effect of immediately making your password database more secure if stolen without any effort on the part of your users.

the User model:

devise :encryptable

the devise-users migration file:

t.encryptable

Are these settings available for you?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top