According to PHP's doc, bcrypt salt are made of
"$2a$", a two digit cost parameter, "$", and 22 digits from the alphabet "./0-9A-Za-z"
So, if i use the crypt() function to hash my passwords, the resulting output include the first 7 chars ($2a$10$, if 10 is the cost parameter) as a part of the salt - and, according to all examples i was able to find across the internet, this complete output is written to db.
I'm wondering what's the point in storing those first characters with the rest of the salt and the encrypted data. Their meaning is fully clear to me, but i can't really understand why such informations should be written alongside the rest of the hash. Aren't they "just" informations about the algorithm and the adaptive cost of the computation? So what's the benefit in storing such application-related info? And (even if may sound childish) why disclosing them to an attacker which can eventually grab my database?
The reason is because of how crypt works. It's designed so that you can do the following
So by storing everything, you don't need to recreate the salt string every time...
And the point of a salt is not to be secret. In fact, it is not meant to be secret. It's meant to foil rainbow tables. remember, if they can grab your database, the chances are high they can get other things as well, so putting the salt elsewhere isn't really going to give you much.
Besides, the salt won't help much. BCrypt is designed to be CPU-Hard, which means that brute-forcing (even with knowing the salt) is impractical. That's why you have a cost parameter. So don't worry about "hiding" the salt. Just store it along side the password and you'll be fine...
Not to mention that what happens if in the future you want to tweak your algorithm? For example, let's say you want to increase the cost parameter due to better hardware being installed. If you didn't store this information with the password, all of your stored passwords would become invalid. This way, each password stored has all the information necessary to verify it. That way, you can check on valid login if the hash is the current default, and if not rehash and update the database with the new one. It prevents the issues associated with updating and improving the hashing methods...