Is there a cryptanalytic reason why a company that has a database full of MD5/SHA1 hashes can't perform a one time upgrade by computing bcrypt(salt, the_old_hash) for every hash they have in the database and then when someone logs in do bcrypt(salt, md5/sha1(password)) to check the password?
That's a perfectly reasonable approach — we did that at PBworks a long time ago. Totally transparent to users if done right. You can also declare password bankruptcy and zero out everything. That forces password resets for your entire user base. The latter approach doesn't go over so well with users or support staff but it is much simpler.
That's what I did when I migrated our application to bcrypt some time ago.
I had some questions about whether using an md5sum as the bcrypt input, with much less keyspace (only hex characters) had any impact on security but nobody could/would answer.
I'm guessing that knowing that the plaintext for the bcrypt hash is always going to be 16 characters of 0-9,a-f might have some impact on crypto analysis but considering the passwords most people use I'm guessing it's only going to be a net win in terms of entropy.
Yeah sure, bcrypt(salt, md5/sha1(password)) is in general less "secure" than bcrypt(salt,password)#, it's still more secure than md5/sha1(password).
# Note though, that you need at least 20 printable ascii chars to get the 128 bits of entropy possible in an MD5 hash, so for _most_ passwords, you could optimize your cracker by only bruteforcing bcrypt(salt, md5/sha1(password)) using shorter strings as password guesses rather then needing to bruteforce the whole 128 bit MD5 space. With bcrypt and salt though, that turns into an "only practical for state-level attacker" I think.
I've been wondering the same thing myself recently. I know of a number of legacy systems that could do with this but I'm unsure of how cryptographically safe it is (bcrypting md5. Would love if someone with knowledge in the area could confirm that it's ok.