The security in a hash function is not that the mechanism is unknown - it is that the hash function has been proven over time to be secure. For example, uniform distribution over the keyspace, and has cryptographic properties such as collision resistance, preimage resistance and second preimage resistance. For password hashing, collision resistance and second preimage resistance properties do not matter - it is only preimage resistance that is important:
for essentially all pre-specified outputs, it is
computationally infeasible to find any input which hashes to that
output
A home grown hash function cannot be demonstrated to have such properties without the eyes of other cryptographers to properly scrutinise your algorithm.
A secure hashing algorithm cannot be reversed if it is used with a salt. The only way an attacker can find out the password from gaining the hash and its salt is by guessing the password. That is, they will hash each guess and find out if it hashes to the same password when the salt is added.
Using password_hash
in PHP without the $algo
parameter will always use the most secure algorithm at the time. A secure hashing algorithm is slow so that if an attacker manages to get the hashes and salt that they have to wait a long time to run through their password guesses. So a real user logging in has to wait 1 *
the slow algorithm, say one second. An attacker trying 10 million password guesses would have to wait 10,000,000 seconds. You should assume they have better hardware than you, so in reality these maths don't hold out - the point is that a slow algorithm will sufficiently slow their attack. The current password_hash
algorithm, which is bcrypt, has been proven to be slow without any shortcuts available in order to find whether a given password guess results in the password hash.