0

just started researching on the latest PHP encryption methods, I've found out my favorite algorithms are compromised. MD5 is no good, SHA-1 has "found flaws", SHA-512 isn't "meant for passwords", these are all from various StackOverflow sites.

HMAC as of 2011 had "no known attacks", and PHP's password_hash is a new addition that uses a "strong one-way algorithm".

I have heard good things about HMAC + MD5, though it has been suggested it would be best to use an algorithm that has yet to be compromised. I see bcrypt is an add-on, there is the native crypt() and now mcrypt? But password_hash handles all of these?

To me, it's all starting to sound like a deadly game of what sounds best. Can someone with adequate knowledge on the subject answer: Which PHP encrpytion method(s) compatible with password authentication are currently most secure and have no known vulnerabilities? In other words which method produces the hash that is least likely to be maliciously generated? Does any native PHP functionality make the list?

  • 4
    A "hash" and "encryption" are not the same thing, you need to make your question much more specific if you want helpful answers. That is — what exactly do you want to accomplish with "encryption"? – Joel L Dec 23 '14 at 1:57
  • 1
    "Cryptographically stronger" is not a specific technical property. What's best depends strongly on what you're using it for. – cpast Dec 23 '14 at 1:57
  • Thanks all, I understand the hash is a product of encryption and have updated the question to reflect that better – John Dec 23 '14 at 2:13
  • 3
    You're still mixing up all kinds of different techniques. Encryption, message authentication, password hashing and plain hashing each has a specific purpose. Asking us about the “best” of those is like asking whether you should buy a Porsche, a tank or a bicycle. It obviously depends on what you want to do. – Fleche Dec 23 '14 at 2:35
  • There are three major applications of cryptography: a) transmitting data securely to another party, b) storing data securely for retrieval by yourself, and c) storing passwords, i.e. checking whether current data matches stored data. If you could recast your question in terms of one of these, perhaps we can help. If you have questions about two or more, them you will need to ask more questions; take them one at a time. – Bob Brown Dec 23 '14 at 3:07
3

The new password_hash introduced in PHP 5.5.0 creates a very strong one way hashing algorithm. All information that's needed to verify the hash is included in it.

I tried running a loop for 5000 times, and every hash for a single password was a unique hash. To create a password hash you can simply use :

$password = '170991';
$hash = password_hash($password, PASSWORD_DEFAULT);

To verify the password, we can simply use:

password_verify($password, $hash);
2

As mentioned above, your choice of cryptographic primitive is going to depend on what you want to do with it.

For password storage, you are going to want to use a hashing algorithm. A hash is a one-way operation which will give you a unique, deterministic output for a given input, but it is impossible to reverse the operation. For example, if I use the sha-1 algorithm on the string 'password', I will get the output '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8' every time. It's not possible to take the string '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', reverse the hashing operation, and get the string 'password'. This way you can authenticate the user by hashing the password they provided by logging in with the hash that is stored in the database, and if your database is stolen (via SQL injection or some other means) the attacker is not able to obtain the user's password.

What about password cracking? If an attacker is able to get access to the password hashes of your users, they will try to crack them. They will take a guess as to what the cleartext password is, run it through the hashing algorithm, and compare it to the hashed value that was stolen from the database. A custom-built password cracking rig can do this very rapidly, so you should take steps to defend against it.

Enter the Key Derivation Function (KDF). A KDF is similar to your standard hash, with one difference: it's very slow. It will basically hash the input over a specified number of iterations, and only after completing that specified number of iterations will it come out with the correct value. The end results is that an attacker must spend much more time to recover the user's password, which will buy you more time to respond to the breach/reset your user's passwords, etc.

So to take a long, circuitous route to your answer, you want to use a KDF, such as PBKDF2

0

The nice thing about PHP's password_hash() and password_verify() functions is that they are designed with the future in mind, but they are also designed to be backward compatible.

The hashing algorithm that password_hash() uses to create a hash is stored in the output produced by password_hash(), and this is how password_verify() knows which algorithm to use to verify a given password against a given hash.

As newer/stronger hashing algorithms are invented in the future, these will be incorporated in the password_hash() and password_verify() functions in future versons of PHP. But, because the hashing algorithm is stored in the output of password_hash(), this pair of functions will always be backward compatible. In other words, a hash created today using password_hash() will be possible to verify years from now using password_verify() in a future version of PHP, even if the algorithm used to create the hash today is obsolete by that time.

So, if you use password_hash() and password_verify(), you will always have the benefit of the latest hashing algorithms available at the present time, and you will always be able to verify hashes created using these algorithms in the future, even if those algorithms become deprecated by that time.

0

these are all from various StackOverflow sites

It must be true then? Taking the case of md5, yes, it is susceptible to collision attacks which can be applied to signatures and hence to certificates (and sha1 is very similar to md5 but with a bigger hash and and more rounds). However applying this to passwords is a very different proposition. In order to apply the attack method to passwords you would need:

  • a copy of the hashed password
  • from a service which accepts very long passwords

There are other ways to attack such a system - notably rainbow tables - but use of a suitable salt provides a lot of protection.

If sha512 is not suitable for securely hashing data, then we're all in a lot of trouble.

Some other answers here mention password_hash() but this is an API not an algorithm. Password_hash is an updated version of crypt() without the backward compatibilty for weaker hashing methods. At the time of writing, password_hash() only supports bcrypt. Bcrypt is probably stronger than md5 and sha1; none are known to have algorithmic weaknesses, but that does not mean that none have algorithmic weakness.

As to which is the most secure method currently available, my guess would be pbkdf2 with a random salt and lots of iterations of whirlpool or sha512. Whether that is appropriate for your application is a much more complex question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.