1

ASP.net has a System.Web.Helpers.Crypto class for hashing and verifying passwords. It appears to generate the salt on the fly and store it as part of the password hash.

My question is, as computers become more powerful and the number of iterations need to increase to help protect against brute force attacks, how can you increase the iterations of the existing passwords?

The number of iterations is hard-coded into the helper. Changing it to a larger number will increase the number of iterations on new passwords, but also increases it unilaterally for all passwords when verifying them. Won't this break password verification for older passwords?

To plan for the future, wouldn't you want to store the salt and number of iterations?

Also, is it possible to "strengthen" existing password hashes by performing additional iterations, or do the iterations all have to occur as one operation?

Sam
  • 9,933
  • 12
  • 68
  • 104

3 Answers3

3

That helper does in fact store a prefix indicating the algorithm and number of iterations used, so if the algorithm changes in the future old passwords can still be verified.

We considered bumping the default from 1,000 to something higher. However, when we did this the new CPU hit was unacceptable. It's OK for a consumer device to require 1,000,000 iterations since you wouldn't really care if your tablet or phone takes 0.5 seconds to log you in. But when a web page takes a measurable amount of time to process login requests.. well.. you don't want users to DoS the server just by logging in. :)

1,000 iterations is still unfortunately the best tradeoff behind offering increased security (over a straight-up salt and hash) and keeping the web server responsive.

Levi
  • 32,628
  • 3
  • 87
  • 88
  • Levi, in looking at the code I cannot locate where it is storing the prefix that contains information about the mash method or number of iterations. The number of iterations seems to be hard-coded in both the HashPassword and VerifyHashedPassword methods. Are we talking about the same library, or is there a newer version I'm not seeing? Or is that part of the Salt and/or Subkey? – Sam Feb 03 '14 at 17:28
  • 2
    @Sam If you look in the comments of the class. You will see that code has been put in to save the password as "version 0". Which defines the specifications to be: `PBKDF2 with HMAC-SHA1, 128-bit salt, 256-bit subkey, 1000 iterations`. I assume that if you created more "versions" you could potentially modify the code a bit to cater to different versions of passwords (and thus different iteration count). The version number is simply saved as a single byte at the first byte of the derived key/password (version 0 having a version byte of `0x00`). – initramfs Feb 03 '14 at 17:34
  • @CPUTerminator - Thanks, I see the extra byte at the beginning now. – Sam Feb 03 '14 at 17:57
2

You are correct in saying that storing the salt and iteration count is better for future planning, just look at PHP's password_verify().

Not only has the iteration count (called cost, not exactly iteration count but based on the same concept) and salt been stored with the derived key, the algorithm is stored too in case the algorithm needs to be replaced in the future.

The System.Web.Helpers.Crypto class uses PBKDF2 to hash passwords which internally uses a hash algorithm over a defined number of iterations to hash a password. Since the internal operations are all non-reversible and that the "iterated" segment isn't the final segment, performing additional hashing does not work. The whole password needs to be rehashed from its original plaintext source.

Generally, the procedure of rehashing passwords occur when the user next logins in again. At this point the system can determine if the user's password needs to be rehashed and proceeds to do so accordingly if required. Not only does this avoid the cost of running a major rehash operation which may cause downtime, it is the only time the user's plaintext password is available again. Passwords should be rehashed if there is a possibility of vulnerability in the near-future as opposed to the time a vulnerability is fully exposed as it may be too late at that point.

If security of data is a concern as well as planning for the future, I suggest you use another class (perhaps make your own) which allows for a custom number of iterations and stores all the relevant data within the derived key/hashed password itself.

initramfs
  • 8,275
  • 2
  • 36
  • 58
1
  1. No, you can not "strengthen" existing passwords - changing the number of hash iterations would break existing verifications. Do not change the hash settings unless you want to force all current users to create new passwords. If you were encrypting instead of hashing this would be possible (but don't do encryption).

  2. We use a common helper library for salting and hashing that lets us adjust the number of hash iterations for each project, so we can increase the iterations arbitrarily. If you are concerned about future-proofing, this may let you scale up in the future.

Generally we salt and then hash around 100 times using a combination of algorithms (SHA256, MD5, etc). The number of iterations and the hashing sequence is part of the individual project settings - we do not store it in the DB with the salt and the hash results.


EDIT:

It occurs to me now that (in general) you actually could hash existing password hashes more times to bring them in sync with updated hashing functionality - as long as the first part of your new hash routine is identical to your existing one. For example, if you hash 10 times currently and are changing it to 100 times, you could hash existing values 90 more times and update the database. If the Crypto implementation is not salting along the way, I would expect 10 + 90 iterative hashes to produce the same result as 100 hashes.

However, if you messed up the process, you could end up corrupting the existing passwords of all your users. I would be reluctant to implement something like this unless I really needed to.

brichins
  • 3,825
  • 2
  • 39
  • 60
  • p.s. See the discussions [here](http://stackoverflow.com/questions/3559437/many-hash-iterations-append-salt-every-time?rq=1) for further reading – brichins Feb 03 '14 at 17:07
  • 100 times is not nearly enough. Using a combination of algorithms is suspicious too. Please see https://crackstation.net/hashing-security.htm – ntoskrnl Feb 03 '14 at 17:40