I am trying to understand password_hash fully in order to be able to explain it for an auditor.
Based on my searching for an answer, I understand that the passwor
I find this article incredibly useful to understand how to correctly hash passwords. It explains how hashes can be cracked with various techniques if the hashes are weak, and how to hash passwords correctly to provide sufficient security.
If I supply a higher cost (say 12), will it still generate a random salt since I am not supplying a salt value
Yes it will - as the documentation says if salt is omitted, a random salt will be generated by password_hash() for each password hashed (this means if you omit the salt value from your options array, it will be generated by password_hash() function defaultly). Moreover, the salt option has been deprecated since php 7.0.
why increases to the cost value increase security?
This is also explained in the above article in section Making Password Cracking Harder: Slow Hash Functions. The higher the cost is set to, the slower is the hash function. The idea is to make the hash function very slow, so that even with a fast GPU or custom hardware, dictionary and brute-force attacks are too slow to be worthwhile. The cost should be however set to reasonable value (based on the specs of your server), so that it doesn't cause significant time delays when verifying users' passwords.
More, is CRYPT_SHA512 stronger that CRYPT_BLOWFISH for hashing?
Read this post about their comparison.
Generally speaking:
You always should apply a salt when hashing passwords, to have a different hash even if you have the same password. This increases security by "preventing" people from using rainbow tables to crack the password.
But bcrypt handles the salting on its own!
Back to your original question:
The cost is used to make it "costly" to crack the password with a dictionary/brute force attack.
Bcrypt basically hashes the password over and over, which makes it time consuming (=costly) to obtain the password to a given hash. If you try to find a password for a hash (brute force attack) you have to calculate billions of password hashes. When each hashing takes "$cost" times as long, then a brute force attack is not feasible. Even if you can calculate the hash for a potential password in milliseconds.
In simple terms: If you have a password hash for SHA-1 (unsecure, don't use it!) with the salt (as this is usually contained in the hash) and you want to hack it then you have to hash all possible passwords + the salt and when you find the combination with the same hash, you found a possible password for this hash.
Let's say you use a good salt and a long enough password, then you need something like 1-5 seconds for a password hash. If you use the blowfish approach with cost=10 you need 10-50 seconds for a password hash. For a single password, this is no big deal. So a directed attack for a single hash is still simple, but usually people obtain large lists of user and password combinations and they are interested to get the passwords for all of them quickly. Then this is much less lucrative for the bad guy, as he needs 10 times the CPU power to calculate all that stuff.
Password hash works by using crypt()
in basically a wrapper. It returns a string that contains the salt, the cost and the hash all in one. It is a one-way algorithm, in that you don't decrypt it to validate it, you simply pass the original string in with your password and if it generates the same hash for the provided password, you're authenticated.
It's best to omit the salt and let it generate one for you. If you use only one salt, it makes it easier to break all your passwords instead of just that one. Salts can be generated regardless of the cost.
Cost (an exponential value) refers to how much effort goes into generating the hash (where higher = more computing power to generate a hash). Don't set it too high or you will bog your login scripts down.