23

The software that our company builds just went through a security audit. The auditors flagged our use of MD5 for hashing passwords that users can set if they want a password on their files. Having looked in to it, it seems that I should replace it with PBKDF2.

But to remove all MD5 hashing methods from the software this will mean users will need to temporarily lose all their passwords? As in, we will need to communicate to customers that if they update, all their files will not be password protected? I mean, I can check that an old hash exists and force them to manually set a new password but the password could be set by anyone which seems like kind of a big flaw. If an attacker has access to their file and the new version of our software, they will get access to the file with out password.

StackzOfZtuff
  • 17,783
  • 1
  • 50
  • 86
robertkroll
  • 333
  • 2
  • 4
  • 2
    This sentence give me the impression that you have a much more serious security problem than the choice of password hash: `If an attacker has access to their file and the new version of our software, they will get access to the file with out password.` – kasperd Jun 01 '15 at 11:39
  • Is it simple the use of MD5, or MD5 without salts? MD5, while not a great choice anymore hasn't been broken for password hashing. If you're not using salt, that's a major problem. Unfortunately auditors don't always understand the finer points of what an obsolete hashing algorithm is. Personally I wouldn't use MD5 anymore for anything, but MD5 with sufficient salts isn't a horrible problem. – Steve Sether Jun 01 '15 at 18:25

3 Answers3

35

This is a common problem.

The usual answer is twofold:

  • For users who haven't logged in since the change: use the old hash value as the input for the new hashing scheme.
  • Whenever somebody logs in after the change: Use the new password directly as input for the new hashing scheme.

Use an additional column in the new table to indicate how the new hash was calculated.

Further reading

StackzOfZtuff
  • 17,783
  • 1
  • 50
  • 86
  • 16
    You can also update the password hash after a successful login: Whenever a user has successfully logged in, you know the plain text password and can use it to update the password hash using the new scheme. – Jost Jun 01 '15 at 10:32
  • @Jost Yikes, then you incur the overhead of re-hasing and re-persisting the password on every single login, even though 99.999999% of the time, nothing has changed. This really only needs to occur once. – Brandon Jun 01 '15 at 16:18
  • 1
    @Brandon You only need to do that for users who haven't already got a password with the new scheme. You know who they are either by looking at the additional column indicating how the hash was calculated, or because you only verified their password using the old hashing algorithm. – thelem Jun 01 '15 at 16:56
  • Right, that makes sense. I thought you were suggesting to simply re-save it every time just in case, which certainly simplifies things, but is high overhead. You meant to persist a column indicating whether it has been re-hashed or not. Sorry for the confusion. – Brandon Jun 01 '15 at 17:15
  • It would be a little wasteful but it wouldn't be terrible. You already have to hash the plaintext to see if it matches the new scheme anyway. You have to repersist too, but you're probably writing a "last login time" anyway so you probably have a database write on a successful login already. I'm not suggesting doing it everything should happen, but I also don't think it is anything that will hurt anything. – corsiKa Jun 01 '15 at 21:38
10

Why not run a PBKDF2 over the output of the MD5 hash? The resulting hash should still be valid and it can be used to convert your old hashes to new once without requiring password resets from your users or compromising your older users.

Note that the resuling hash is both at least as secure as PBKDF2 and should not be significantly more expensive then just plain PBKDF2 (MD5 being easy to caculate it the reason it's a bad idea to use it). You should be able to explain/mark that this is a secure way of handeling things in code if you are affraid you will receive warnings about it in the future.

Note that you can combine this with StackzOfZtuff's method as a way of keeping the user passwords that have not yet been updated save, by updating a user's password when they log in towards PBKDF2 but for now changing it into PBKDF2(MD5) as a way of keeping the user passwords safe for now.

Thijser
  • 353
  • 3
  • 12
  • 1
    At some point, you might want to remove the old hashing for a few reasons (computational costs, complexity, maintenance concerns, etc). While certainly an option, you will probably want to eventually remove the code that is essentially unnecessary. – Ellesedil Jun 01 '15 at 14:32
  • Yes but do note that any other method will either leave your older users exposed (the once who don't come back within a given time) or require the removal of all older passwords after a given time. – Thijser Jun 01 '15 at 14:46
  • 1
    It seems that is what I will have to do, but this issue came up from a security audit by static analysis of our software. Something we are required to do regularly. It would be nice to remove it once and not get pinged about it again in the future but at least we will be able to claim that this flaw is now mitigated. – robertkroll Jun 01 '15 at 15:57
  • If you just write several comments informing whoever is doing the analysis then they you shouldn't get pinged about it anymore, if you are working dirrectly with a program going over your codebase then you will most likely have a way of disabeling a specific warnign (@supress or somesuch). – Thijser Jun 01 '15 at 16:45
  • 1
    @robertkroll They shouldn't be flagging up that md5 itself is insecure, just that md5 on its own is not enough to protect a password. If they flag up to you that md5 + PBKDF2 is insecure because of the md5, then the don't understand the reasons behind their own guidelines. The md5 is redundant when combined with a secure hash, but that isn't a security risk. – thelem Jun 01 '15 at 16:52
  • @thelem You're right. But these are auditors we're talking about. They often don't make these fine (and entirely correct) distintions. They just have a checkbox, and want to address the checkbox in the most unambiguous, limited knowledge way. I just recently had an auditor claim we had to "upgrade to the latest version of apache" (and no, not the current patchlevel in our linux Distribution). It took several pages of documentation and screenshots to prove to them that the latest patch level of an old version fixes all known vulnerabilities. – Steve Sether Jun 01 '15 at 18:33
  • md5 + PBKDF2 may be more secure than md5 alone, but it is likely less secure than PBKDF2 - one of the weaknesses of md5 is collision, which allows shortcuts. That means the input space for your PBKDF2 is limited. If someone can get your password database, there's every chance they can also get to your code with your hash algorithm, see that you do PBDKF2(md5) and take advantage of this. – HorusKol Jun 01 '15 at 23:15
  • @Ellesdil: >At some point, you might want to remove the old hashing for a few reasons. This is what I don't understand. Our client is fat-client, enterprise software. There is no way to ever safely remove MD5 in the future because I have no idea which versions users will be upgrading from. – robertkroll Jun 02 '15 at 06:02
  • @robertkroll If you have a boolean column recording which passwords are md5, then you can report on which users still need the old hashing algorithm. If you are rehashing when an md5 user logs in, then after a year (or other suitably long time) the only users with md5 passwords will be those who haven't logged in all year. You can then contact those users or even just disable their accounts. – thelem Jun 02 '15 at 15:21
  • Maybe even better would be a hybrid where you use the booleans to log whatever the md5+PBDKF2 or just PBDKF2 has been used. This should keep your users safe while in the transition period. – Thijser Jun 02 '15 at 18:01
  • @thelem It's not a web application. Users can be upgrading from potentially _any_ old version of the software. Therefore transition periods are not so straightforward: if they are upgrading from only MD5 hash to after MD5 was removed (skipping the MD5->PBDKF2 transition), they will have to reset their password thus leaving them temporarily vulnerable. – robertkroll Jun 03 '15 at 06:39
  • @robertkroll Do you really promise to migrate data from any old version to any new version? That sounds a difficult promise to keep, for exactly this sort of reason. Still, after a certain number of versions had been released you could lock accounts still using md5, and force them to go through your lost password process. – thelem Jun 03 '15 at 11:24
2

We've just implemented this - moving from salted md5 hashes to blowfish (via the PHP password API).

We've managed the migration by putting a flag in the database - if the flag is not set, then that record is still using the salted md5. We authenticate with the old method, and then rehash with the new method. We're implementing a policy where, after a fixed from the production release of this new method, accounts using the old algorithm will have their password field emptied - requiring a new password to be set, and blocking access until it is reset.

One nice thing about the way the PHP password API works is that the string returned from the hashing functions contains information on how it was hashed (which cryptographic method, parameters for the method, and a salt), along with the hash all in one string. This strategy means we can change the encryption method and parameters in a config file, and the API provides a function which compares the configuration with the parameters in the current stored value, informing you if a rehash to the new parameters is necessary.

HorusKol
  • 139
  • 7