0

I am looking for a good one way encryption/hashing for safe storage of passwords using one of the algorithms provided by my host.

Here's a list of all the algoritms provided by the host: http://www.eresig.tk/hash.php

NullUserException
  • 83,810
  • 28
  • 209
  • 234
SnackerSWE
  • 649
  • 1
  • 10
  • 19
  • 1
    You should [use bcrypt][1] to make it harder to crack the hashes. [1]: http://stackoverflow.com/questions/4795385/how-do-you-use-bcrypt-for-hashing-passwords-in-php – Bluewind Sep 19 '11 at 17:50
  • Try using [PHPass](http://stackoverflow.com/questions/1581610/how-can-i-store-my-users-passwords-safely/1581919#1581919) if at all possible. – Jacco Sep 20 '11 at 07:36

3 Answers3

8

None of the above. The problem with general purpose hashing functions is that they are fast, which means an attacker could realistically bruteforce a huge amount of passwords very quickly, with the prospect looking bleaker as computers get faster.

Use bcrypt instead, which is built-in to PHP, with support for all platforms starting at 5.3.0. If you are using an older version of PHP, you can set up bcrypt with the Suhosin patch.

The advantage of bcrypt is that it has a work factor which you can set to slow down the hashing process. You are not overly concerned if it takes you a little time more to check if a given password is valid, but it will take an attacker significantly longer to bruteforce passwords.

If you want to go beyond that, you might also want to check out scrypt.

Community
  • 1
  • 1
NullUserException
  • 83,810
  • 28
  • 209
  • 234
  • But why none of the above then? It lists "Blowfish" as fourth element. – NikiC Sep 19 '11 at 17:53
  • @NikiC You need to use `crypt()` for bcrypt, you can't use `hash()` for whatever reason. – NullUserException Sep 19 '11 at 17:55
  • Yeah, sure. I was only trying to say the Blowfish is part of the list, even if not in the hash but in the crypt section ;) – NikiC Sep 19 '11 at 17:57
  • If I want it to be slower, isn't it possible to to loop a hash several times? For example: `for ($i=1;$i<1000;$i++) { $hash=hash('sha512', $hash); }` – SnackerSWE Sep 19 '11 at 18:11
  • @SnackerSWE Yes. But you still won't get results as good as using a native function which is designed for that specific task. (E.g. your implementation is loosing entropy as it doesn't add the salt on each iteration) – NikiC Sep 19 '11 at 18:19
  • This is extremist/alarmist at best. Hashing functions have initialization vectors to avoid brute-forcing using rainbow tables. Implementing 'best practices' for password length and complexity make targeted brute-forcing impractical. – Louis Ricci Sep 19 '11 at 18:31
  • @NikiC is bcrypt the same as "crypt_blowfish"? EDIT: Of course I use salt though, I just didn't show it in that example. – SnackerSWE Sep 19 '11 at 18:33
  • @Snacker: Yes, it goes by different names. In PHP you can create blowfish hashes using the crypt function: http://php.net/crypt – NikiC Sep 19 '11 at 18:35
  • 1
    @LastCoder Adding a unique salt will make rainbow tables useless, but do nothing to stop a bruteforce attack on a single password + salt hash – NullUserException Sep 19 '11 at 19:54
  • @Snacker Doing that would be close to doing the one thing you shouldn't do in crypto: roll your own implementation. Rehashing something multiple times may or may not increase security, whereas the authors of bcrypt explain the reasoning behind what they did here: http://www.usenix.org/events/usenix99/provos.html – NullUserException Sep 19 '11 at 19:58
  • @NullUserException ఠ_ఠ, BCrypt in PHP is implemented differently from the BSD implementation described in the provos article. In PHP, you *do need to supply a salt*! In the BSD implementation, the salting is done internally. So, for PHP recommend [PHPass](http://stackoverflow.com/questions/1581610/how-can-i-store-my-users-passwords-safely/1581919#1581919), instead of the 'naked' BCrypt implementation in PHP. – Jacco Sep 20 '11 at 07:29
1

SHA-256 is more than sufficient for password hashes, just make sure to use a different edit salt for each user. The salt could be the user's ID, a 'created on' time-stamp, a GUID tied to that user, etc... You'd append the salt to the plain text password before hashing.

Enforcing some sort of password 'best practice' would help to avoid any brute-force attacks. Don't allow users to use weak passwords (less than N characters, contains characters from only 1 character set, etc...).

Louis Ricci
  • 20,804
  • 5
  • 48
  • 62
  • -1 for IV. I think you're talking about salting the hash to increase the cost of cracking with rainbow tables. In hashing, the 'IV' is really just the input to the hash function and I don't believe it's ever known as the IV. – jah Sep 19 '11 at 19:23
  • I feel bad now and want to undo my -1 which was overly harsh. SHA-256 is indeed a good hashing algo for storing passwords AS LONG AS THEY ARE SALTED HASHES and the salt is sufficiently unpredictable. – jah Sep 19 '11 at 19:28
  • The term "initialization vector" is normally used in the context of block ciphers, whereas "salt" would be a better word for what you are trying to say. And argue whatever you want, but one can realistically crack an 8 character password hashed via SHA256 within a day. – NullUserException Sep 19 '11 at 19:49
  • I changed IV to Salt for the nomenclatures sake. – Louis Ricci Sep 19 '11 at 19:58
  • @NullUserException - so you're saying that 8 (or less) character passwords wouldn't be part of a password length "best practice"? I sure wouldn't 'argue' with that... seems like a straw man to me. – Louis Ricci Sep 19 '11 at 20:01
  • Studies show that passwords have an average length of less than 8 characters. Additionally, many "password best practices" are arguably looking [more and more pointless](http://xkcd.com/936/) as we get more processing power. That's where bcrypt comes in. – NullUserException Sep 19 '11 at 20:03
  • I personally find it extremely annoying when password policies force to do a crapload of stuff (eg: needs to have a symbol, a number, an uppercase and lower case, blah blah blah), rendering the password extremely hard to remember. I know a lot of people who just write down passwords in sticky notes because they are so damn hard to remember. Is that a good behavior to encourage? I think not. – NullUserException Sep 19 '11 at 20:12
  • A salt should be random - not something relating to the user such as their userid. – Nick Johnson Sep 20 '11 at 01:54
  • @NullUserException- you make it seem like bcrypt is some panacea. The fact that it's 'slower' can be replicated with ANY hashing algorithm, just loop it a significant amount of times. As more complexity (entropy) is added to a password 'best practice' the ability to brute force it is decreased EXPONENTIALLY. Exponential growth is much larger than processor/gpu/gpgpu improvement. A 20 character password with Upper and Lower "BlargidyHelrpaDerpla" that would be easy for me to remember. Tell me how many Eons it would take every supercomputer in the world to brute force that? – Louis Ricci Sep 20 '11 at 11:43
  • @LastCoder Your statement that it can be replicated by looping is wrong, because as I said before, rehashing something multiple times may or may not increase security, whereas the authors of bcrypt explain the reasoning behind what they did in a peer reviewed document. – NullUserException Sep 21 '11 at 00:36
  • Your assertion that I think "bcrypt is some panacea" is also wrong. It's hard to protect users from their own stupidity, but bcrypt is an added line of defense. Also I am not telling anyone to throw password policies out the window. – NullUserException Sep 21 '11 at 00:38
1

Hashing problem is WAY exaggerated on this enthusiast programmers site. In terms of hashing passwords any algorithm would suffice. Especially when this problem compared to other parts of usual php application. Using some strong hash on a usual PHP site is like using a safe lock on a paper door of a straw hut.

If you really want protect user passwords from being stolen using some vulnerability on your site (while such a vulnerability you ought to be way more concerned of) and then bruteforced and then used against these users on other sites, then the thing you really should care of is password strength and salt, not hashing algorithm itself. No hashing technique would protect silly pass like "1234" or "joe".

So, md5 + strong password + average salt is better than usual password + super-extra-cool_hash and quite enough.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
  • +1 For generally correct post, although the "exaggerated" part is a bit uncalled for. Is asking people to use prepared statements instead of `mysql_query("SELECT * FROM table WHERE id ='{$_POST['id']}')` "exaggerated"? I think not. – NullUserException Sep 19 '11 at 19:24
  • "Your site is probably poorly written and vulnerable anyway" is _not_ a good argument against properly securing your users' passwords. Quite apart from anything else, most users reuse passwords, and failing to secure them to the best of your ability is irresponsible. – Nick Johnson Sep 20 '11 at 01:53