You have a plain text password and salt. The plain text password is assumed to be securely random and only known by the user and the salt is no secret and not necessarily unique but stored alongside the resulting hash. Is calling the following on its own and storing the result sufficient?
password_hash = Hash ( password || salt )
Where Hash
is currently considered a "secure" hash function (sha512, BCrypt, etc)
Do people do more? Such as:
- Multiple Iterations: Is there a huge benefit in running multiple iterations? If yes, is it purely a cost advantage? Is the number of iterations dynamic or static? How many iterations?
- Multiple hash functions: Would there be an advantage in using multiple hash functions? For example, three rounds,
sha512 -> BCrypt -> sha512
? - Salt mixing Do people nest salts within a password or just concatenate on the end/start? For example, break the plain password into four sections, the salt into three and join each salt section in-between each password section.
- Unique schemes: Would writing a unique
password_hash
function for each different project be of any benefit? For example, Project A'spassword_hash
function runs SHA512 20 times and Project B'spassword_hash
function runs BCrypt 10 times applying the salt at different ends of the password on each iteration. - "Black Magic": Is there a benefit in adding your own "black magic" to a hashing function? For example, before each iteration you apply some basic bitwise actions or mix up the characters based on a simple algorithm.
- Obfuscation: Would encoding or obfuscating the generated hash to hide its originating hash function make a huge difference? Such as adding or removing N characters to the hash to hide its original length.
Are these actions really necessary, would they make a huge difference (if yes, in what way) and do people use any extra actions like the ones mentioned above in practice?
My Thoughts:
In the end whatever is done with the password will not prevent someone using a stupid password (like 'password' or '123'); other methods not relevant to this question will have to be taken. But it is possible through multiple iterations make the computation more costly thus slowing down or rendering an attack unfeasible by brute force.
Most actions mentioned above will make a large difference to someone who has already gained access to the list of users - emails, password hashes and salts, and wishes to recover the plain passwords. It would not prevent a determined hacker but will deter and hopefully slow them down to give you enough time to make appropriate changes or actions to secure the compromised accounts.
However a lot of this goes against the idea that "the attacker knows all". Assuming the attacker can see how the password hashes were generated (source code and schema) it would make little difference. It would be as significant as changing a database tables column name from password
to ahoy
Regardless, just using password_hash = Hash ( password || salt )
seems too straightforward. Surely people do more?