Sign up ×
Information Security Stack Exchange is a question and answer site for information security professionals. It's 100% free, no registration required.

This question is more of a security policy than a technical security question.

Many years ago I developed an site, implemented Forms Authentication, and stored the user passwords as MD5 hashs. From following basic security news it's pretty obvious that MD5 is no longer useful. I see two possible plans for handling my current users.

  1. Copy old users table into new design and hash the current MD5 into SHA-512. Then when users login I'll hash their input first as MD5 and then as SHA-512. Kinda Rube Goldberg but it doesn't bother my users at all
  2. Force all users to reset their password, checking the old password using MD5, but storing the new password as SHA-512.

Any thoughts? A third option I am missing?

One note: I love OpenID but it's not an option on this site

share|improve this question
also, for those with enough reputation points, shouldn't there be a tag for SHA, to cover questions regarding any of the SHA algorithms? – Justin C Jun 24 '11 at 19:45
Actually, there is no need to migrate from MD5 to SHA-512 (except for "appearances" sake). MD5's collision-resistance is broken, but MD5's one-wayness is still going strong. For password hashing, all that you need is one-wayness. If you want to talk about improving authentication, you'd do better to, e.g., use bcrypt/PBKDF2 to make dictionary search harder, remove the use of passwords completely, move to federated login, etc. – D.W. Jun 26 '11 at 4:30

4 Answers 4

up vote 10 down vote accepted

I've had to solve this same issue twice before:

  1. My first web app, I actually knew enough to MD5 hash users' passwords; I did not, however, know about salt, and worked that in later.
  2. Actually the same web app, a few years later, when I decided to "upgrade" to SHA-512 from the existing MD5.

In both cases, I used neither of your options, but rather option 3: Upon a user's next login, use the password to generate the new hash and replace the old one (after verifying against the old one).

In the case of adding a salt, this was pretty trivial: All I did was default everyone to a salt of "" (empty string), which could be concatenated and then hashed without having any effect whatsoever on the resultant hash; once authenticated, I generated a new salt for the user and then re-hashed the password, saving that new result.

Upgrading from MD5 to SHA-512 was a tad trickier, but by simply looking at the string length of the has in the table (I didn't use a new column for the new hash, merely expanded the existing one to accommodate the longer hash) I could tell which algorithm to use and then authenticate the user appropriately; once authenticated, if they were still on the old hash I would compute a new one (also taking the opportunity to generate a brand new salt) and store that.

In both cases I of course did eventually run into the situation where further down the road "old style" passwords still existed. After waiting an appropriate amount of time (e.g. 6 months), simply decide that those that haven't logged in since the new style was adopted are "inactive": Generate and store a new, completely random password for them (using the new style of storing it, of course), and if they ever did come back they would have to use your password reset mechanism to regain access. (Alternatively, leave as-is, but effectively invalidate it by simply dropping the code for the old style.) You could (if applicable) also send an e-mail to these users, asking them to log in to complete a security upgrade on their account, before invalidating their current password.

This approach does involve additional code in the authentication routine, of course, but it's only temporary -- once everyone has upgraded (whether by logging in or by being "forced" in as in the previous paragraph), you can remove all code responsible for performing the upgrade. Security upgrade complete, with the majority of your users (and all of your regular users) having never noticed a thing!

share|improve this answer
+1 I like some of your ideas. I do have the users emails stored, so I could use that to offer a password reset down the road for anyone who missed the update window. – Justin C Jun 24 '11 at 17:17
@Justin You could also just leave the "upgrade" code in place -- 3 years later (when my web app finally came down), the code to add salts to passwords that didn't have them was still there. There's actually a case to be made that more involved authentication procedures -- which take longer to complete -- improve security by naturally limiting the number of brute force attempts in a given period of time; this is why you'll see suggestions to hash passwords repeatedly instead of just once (although that's primarily to hinder off-line attacks if someone gets your database). – Kromey Jun 24 '11 at 17:23
See, for example, the answer to this question:… – Kromey Jun 24 '11 at 17:26
Option 3 is described in more detail at Upgrading User Password Hashes in Place – David Cary May 19 '12 at 20:40

This isn't a true answer in that it doesn't address your specific question, but I agree with adding another option of federating your IDs. So, whether that's OpenID, Facebook, Google, whoever...the best option for securely storing user credentials is to simply not do it.

TL;DR: Federate authentication if/where possible.

share|improve this answer

Don't do option 1, you lose all of the benefits of the better hashing algorithm. By hashing with a worse algorithm first, then with a better one:

  • You lose all of the collision resistance of sha512. If md5(password1) == md5(password2), then sha512(md5(password1)) == sha512(md5(password2)). I'm not a security researcher, but since you're hashing multiple times, I suspect you would actually increase the chances of a collision (chance of md5's colliding + chance of sha + md5 colliding).

  • The extra bits (512 vs 128) are worthless for the same reason. Hashing 128 bits of information will never give you more than 128 bits of entropy.

share|improve this answer
Collision resistance is not relevant in this application. What matters is the difficulty of recovering the password, given the hash. For this purpose, actually, MD5 is just fine. – D.W. Jun 26 '11 at 4:28
DW: If MD5 is just fine, then there's no reason to "upgrade" the hashes. – Brendan Long Jun 26 '11 at 20:49
As D.W. noted elsewhere, and as covered in the "wiki" here for passwords and at appsec - How to securely hash passwords? - IT Security, the issue is not md5. It is the need for slowness via iteration ala bcrypt or pbkdf2. It is conceivable that someone could break md5 for preimage attacks, as it has been broken for collision attacks, but much less likely. – nealmcb Jun 27 '11 at 3:29

I have used option 2 before in a company needing to do the same thing. No problems with option 1 but 2 seems simpler.

Also use PBKDF2, bcrypt instead of SHA-512 for passwords

Ok Open-ID is out but can you use O-Auth and use something like Twitter or Facebook connect and eliminate storing and managing usernames and passwords altogether?

share|improve this answer
I can preach, but when a client writes the spec with you and they have particular feelings about who handles what data, sometimes you just gotta do what the client wants. If it were a bigger deal in my eyes I would dig my feet in the ground, but with solid encryption I'm comfortable with local storage, just gotta replace MD5. – Justin C Jun 24 '11 at 15:31
@justin-c fair enough got to listen to the person paying the bill. – Rakkhi Jun 24 '11 at 19:04
@JustinC "sometimes you just gotta do what the client wants." as a professional you still have a duty to tell the client when he is wrong. In some other engineering fields, doing what the client asks can send you to jail. – curiousguy Nov 16 '11 at 2:27

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.