PHP now has a secure password lib (I say that with great trepidation) in its master branch. At first, I thought “cool, here’s something that will make our lives better!” Then I read it.

This is bad, and here’s why:

It changes crypt.c

This bit of code changes the behavior of crypt.c (in ext/standard/) and as a result changes how the function is called, and has the amazing potential to cause some serious bugs in future.

It has a default which is open to change

+#define PHP_PASSWORD_DEFAULT  PHP_PASSWORD_BCRYPT

This line should strike a blow to the heart of anyone who cares about backwards compatibility. Why? because developers are lazy. Really lazy. When someone changes this to scrypt or hallowedcrypt we toss backwards-compatibility out the door and ask for developers (and users!) to complain it works on one version of PHP and not another.

This should not be a hard-coded value, but instead something kept in one of the many configuration sections.

It won’t be in production for at least another year

Web hosts rarely change. Many webhosts today (that I have interacted with) actually have the option to change the version of PHP you’re running under and most of them default to PHP4. Let’s assume for the moment it takes Debian a year to include this version, most webhosts will take another 2 years at least to include this.

It doesn’t fix the problem so many PHP devs have

The problem isn’t secure passwords, but securing of passwords. A fundamental distinction, given that storing passwords plaintext isn’t secure to begin with, but saving them as a box of md5’s is just as bad. So much PHP software does exactly that, and tosses it into a database using a weak password. MySQL is not the most secure thing on the planet, and being able to make MySQL render its internal password table and turn around and log in pretty easily.

It complains that hash( $salt . $content) is bad — and then uses bcrypt.

I have nothing against the hashing algorithms included in PHP. They span the gamut, from CRC32 to Whirlpool, and even have some obscure ones like Gost.

The problem is, most people don’t really know why hashes aren’t secure. Therefore, they go for other options. Bcrypt is awesome, and people have been using it for everything from verifying passwords to making sure their toaster’s signature is correct. Nothing has been found in bcrypt and that, from a security point, is somewhat scary.

When that major exploit is found for bcrypt, even for cost=1 systems, that now leaves every single application which relies on it open.

There are hundreds of better alternatives

Let’s consider this: Sha256+salt is “okay” when you make your salt something hard to determine. Hell, make it something only php as an application can access. The problem is that so many people use common salts (e.g. NaCl or saltpork).

A better solution is to employ the fact there are many algorithms that look very similar. SHA256 and RIPEMD256 look a lot alike, but they’re different hashes. Technically, you can’t tell a RIPEMD from a SHA hash of similar bit-sizes.

I’ll just toss out something that I use: a hash which iteratively changes depending on the previous hash and uses N algos. Changing this to have a configured list of algorithms that /changes/ from app to app? now one app gets owned and the rest don’t. (source for you who want it)

This needs to be an extension, not a core module.

This would be much better as part of an extension, something optional. Because of how the crypt function is modified (as noted above) I’d be tentative of including this in core.

That said, I have a caveat here.

I’m not an expert. This is my opinion, one of many on this topic. I’m sure the PHP devs have a reason for this, but I don’t plan on ever being able to use this (I have to target PHP4, still the most common version out there).