2

I'm looking for a password hash method for a new server system. The hashes must be generated from PHP code and verified from PHP as well as by a number of applications on a Linux system.

I know that plain or salted MD5 and SHA-1 are not a good solution. I hear that sha256crypt and sha512crypt should be okay today. I once read that the sha2crypt algorithms are now very easily cracked, rendering them useless. I often hear bcrypt recommended. But there's also been multiple issues with bcrypt by now. $2$ doesn't seem to be relevant anymore, but $2a$ and $2b$ are incompatible as I understand it. And at least PHP has a strange understanding of fixing things by reusing the $2a$ prefix for the $2b$ algorithm, making it incompatible. I don't know what $2x$ and $2y$ stand for. PBKDF and scrypt don't seem to be supported by anything so I can't use those.

PHP can generate bcrypt hashes with the password_hash function, but it doesn't seem to be able to create sha256crypt or sha512crypt hashes, neither with password_hash nor crypt which will decide on its own what algorithm to use. I want to specify the algorithm because not all applications support any algorithm.

For now the sha512crypt algorithm looks most promising, considering compatibility first, then security. (A super-secure thing that simply does not work is still useless.) But PHP can't generate those. Am I stuck with crypt() using SHA-1 again? (That's what it does: $1$)

The OS is Ubuntu 14.04 and the applications are exim, dovecot and proftpd for now. PHP version is 5.5.9.

So what should I do? I'm fully confused by everyone right now.

ygoe
  • 121
  • 4
  • It only adds to the confusion and does not answer my bcrypt compatibility question. – ygoe Dec 20 '14 at 16:01
  • 2
    Yes, I should switch my priorities. I know. Tell that everybody else. Meanwhile I've found out that at least two out of three applications that must verify my password hashes do not support bcrypt. And I won't replace the entire OS only for bcrypt support. So while an answer might still be interesting, I can't use it anymore. – ygoe Dec 20 '14 at 18:30
  • 2
    It seems like you've done some interesting research, but also come to some very questionable conclusions. There is a lot of misinformation out there, and of course pbkdf2 and scrypt are supported by lots of systems. Please provide references for your claims of incompatibility, or "problems with bcrypt". Note that password hashing doesn't really require much from a hash function other than being slow, so sha1 or even md5 repeated enough is fine. – nealmcb Dec 20 '14 at 21:25
  • Just use bcrypt –  Dec 20 '14 at 22:01
  • nealmcb: bcrypt, scrypt and pbkdf2 are not supported by Ubuntu 14.04's libc crypt() function. Exim, Dovecot, ProFTPd and libc (for /etc/shadow) rely on that function. So these are unavailable. I don't know where you all live that these are supported. And lastly there are two incompatible variants of bcrypt. That's why I believe that bcrypt is a bad choice. – ygoe Dec 21 '14 at 09:09
  • To the folks that think this is a dup - it is not. It is a detailed API question. To resolve it it seems that someone needs to give an example password hashed with current versions of Ubuntu and PHP, and show that hashing it in each leads to something that can be verified on the other. – nealmcb Dec 22 '14 at 01:42
  • See whether this helps at all: https://crackstation.net/hashing-security.htm (There's example code at the end.) – Bob Brown Dec 22 '14 at 18:54

1 Answers1

2

I don't really understand the limitations you have with 3rd party applications, but I'll address the question you asked.

Instead of focusing on "which algorithm should I trust forever?", you should make your hashing system up-gradable. SSL was invented 20 years ago, and one of the strengths of SSL was that the ciphers were designed from the start to be replaced as new attacks became apparent. As we've seen recently, many ciphers suites have been broken and retired, but SSL itself continues on because it was designed to change.

This isn't terribly difficult. You only need to store the hashing algorithm along with the hash. If a flaw is discovered in a hashing algorithm, change the hashing algorithm you use for new or changed passwords, and the next time a user successfully authenticates, re-store the hash with the new hashing algorithm. Over time users will be upgraded to the new hash.

MD5 and SHA1 are considered broken and shouldn't be used in new hashing implementations. SHA256 and SHA512 are currently well trusted algorithms. I'm not sure what problems you have with finding support for them in PHP, but it looks like they're both directly supported using the crypytography extension. http://php.net/manual/en/function.hash-algos.php

Otherwise I'm sure you can find a library somewhere that supports them.

The other standard precautions are advised. Be sure to use at least 128 bits of randomly generated salt for EACH hash stored. You might consider adding "pepper" to, which is a single salt stored in a place separate from your hash.

Steve Sether
  • 21,530
  • 8
  • 50
  • 76
  • Just as a side note: While I like that idea, no application updates a hash from a password database just because it's supposed to be upgraded. Also, the hashing algorithm SHA-512 is something else than the password "encryption" algorithm sha512crypt, right? There's at least a specific number of rounds that make the hash slow enough. But with a bit of hacking, the crypt() PHP function should do. – ygoe Dec 22 '14 at 20:15
  • 1
    No, SHA512 is SHA512. I wouldn't call it particularly slow. Hashes aren't designed to be slow, they're designed to be fast. That's why you iterate many thousands of rounds of it, if possible. I'm not sure why you don't think anyone would update an outdated hash if it's merely a configuration line change. SSL parameters are updated all the time with merely a configuration change. – Steve Sether Dec 23 '14 at 20:05