2011/5/17 23:38:48
|
---|
|
Password stretchingJust thought I’d ask, does Impress already do password stretching? I just came across it recently and it looks like a simple way to increase the difficulty of offline dictionary attacks against password hashes.
Password stretching is just re-hashing the password a large (but fixed) number of times, instead of just once. The idea is simply to increase the amount of time required to calculate a password hash. If you rehash the password (say) 1,000 times before storing it, then a dictionary attack will take 1,000 times longer to run because the attacker must duplicate this process. Running an offline dictionary attack against a large number of password hashes (eg. if someone captures the database) suddenly becomes a much more time consuming affair. Maybe impossible, if you can crank the difficulty up enough. Obviously this adds some overhead to the login process, but the level of difficulty could be set to whatever level people are comfortable with. The added delay to login might not even be noticeable to the end user. For example, nobody is going to notice an extra 0.1 second delay on login, but slowing hash calculations down to a few per second would severely impede dictionary attacks. Worth a look, or am I already behind the times on this? |
2011/5/18 11:40:34
|
---|
|
Re: Password stretchingoffline dictionary attacks shouldn't work on the hashes because each hash is unique to that user even if they have the same passwords.
ie. if 100 people register, and 50 of those use the same password, in the old version (and current xoops core), then 50 people would have the same identical hash. in ICMS 1.1 this got changed as we introduced 2 salt keys into the equation. 1st key is stored in a file inside TRUST_PATH and stays constant. 2nd key is stored alongside the password in the users table, this key will be regenerated each time a user changes his password. during the password hashing, each salt key is appended to the users password (which is 1st md5'd) which then is hashed again with whatever hash you select in admin. ie. $salt1 = 'gewgerhsggstrhTRHSHGRHJNTJTYHEGTRT54654ey4trrfgdgg92GtWbnmo57usf' $salt2 = 'rgnjeroijgt884t8jf98ehsfdivusdbhviufbnREGRGHSREGSG435439ytfewfwefvn88' $password = 'password' $md5Pass = md5($password) $hash = hash('sha256', $salt1.$md5Pass.$salt2) essentially, both salt keys are a random 64 character alphanumeric string, the md5 hash is 32 characters in length. this means we are sha256 hashing a 160 character password/string i suppose i could improve that by generating a new user salt key & re-hashing the password each time a user logs in. |
_________________
Live as if you were to die tomorrow, Learn as if you were to live forever The beauty of a living thing is not the atoms that go into it, but the way those atoms are put together! |
2011/5/18 17:54:55
|
---|
|
Re: Password stretchingThe salt is an excellent defense against dictionary attacks but it depends on the salt remaining secret. The case I had in mind was the possible breakin to Lastpass a couple of weeks ago, where they think both the hashes and the salt may have been captured.
A lot of our sites are probably on shared webhosting, where there is a fairly high risk of the server getting knocked over. Stretching isn't perfect either, but it might be a useful as an additional last-ditch measure to protect the passwords (which users will have inevitably used elsewhere) when all else has gone wrong. |
2011/5/19 1:17:06
|
---|
|
Re: Password stretchingso what you're essentially saying is that i should do this >
$pass = md5('password'); $salted = $salt1.$pass.$salt2; $i = 1000; $hash = hash('sha256', $salted) $ithash = hash('sha256', $hash . $salted); // 1st iteration where $ithash has been run through a loop 1000 times, in essence it has rehashed it's own hash 1000 times? each time it appends $salted to the equation. hence 2nd iteration becomes; $ithash = hash('sha256', $ithash . $salted); & so on. |
_________________
Live as if you were to die tomorrow, Learn as if you were to live forever The beauty of a living thing is not the atoms that go into it, but the way those atoms are put together! |
2011/5/19 9:41:31
|
---|
|
Re: Password stretchingA good example is at http://www.openwall.com/articles/PHP-Users-Passwords
Several other projects have adopted this library for their password hashing (Drupal, WordPress and Vanilla are among them) What is unique about his approach is the hash method, the salt and the number of iterations is encoded and embedded in the final hash. I guess it doesn't really matter where you store the salt, #of iterations or the method - if you get the db, you'll have them if you store it there, if they're stored in the filesystem, you could retrieve them, too, with an improperly secured host. He also uses only 5 - 30 iterations for stretching. One could randomize the identifiers and store them in the TRUST_PATH, making it more difficult for an intruder - they would need the db and access to the file system on the server, as they do now with our current scheme. Another interesting point is the timing leaks that can expose valid usernames because an invalid username returns more quickly than a valid username. (Usually, invalid usernames skip the hashing portion of authentication) |
2011/5/19 10:11:04
|
---|
|
Re: Password stretchingQuote:
the solution to that is to create a dummy hash system if someone is randomly trying to guess usernames, so although the user doesn't exist, the system still goes through the hashing method before rejecting it. |
_________________
Live as if you were to die tomorrow, Learn as if you were to live forever The beauty of a living thing is not the atoms that go into it, but the way those atoms are put together! |
2011/5/19 14:40:19
|
---|
|
Re: Password stretchingAs for timing leaks... a random delay?
|
2011/5/19 17:33:18
|
---|
|
Re: Password stretchingThe author of the library I linked to used a fake hash and went through the process before returning the results, producing about the same time delay for both types of users.
I was incorrect in saying the library only hashes 5 - 30 times. That is the range for the number of times the iterations are doubled. At level 5, there are 32 iterations, at 6 there are 64, then 128, etc. |
2011/5/19 22:27:03
|
---|
|
Re: Password stretchingQuote:
Yeah, except you probably only need to use the salt in the initial interation, as the interations after that are just to consume time. It would probably take a bit of experimentation to find an appropriate value for $i (ie. one that won't kill an overloaded shared webhosting machine but still offers good protection). Might work best as an adjustable preference. Apparently Lastpass will be hashing 100,000 times, but I imagine they can afford dedicated hardware to do that. Quote:
That should help. |