Sivut

lauantai 23. lokakuuta 2021

Hash baby Hash

In this case, "hash" means messing up passwords. Sorry, but this is the English version. Nerds and half of the world do understand.

But how to hash passwords on a website? As a developer, I must know how to store passwords securely. For the following reasons:
1) Many web attacks aim at stealing your users’ passwords. If passwords are stolen, I must make sure the attacker cannot decrypt them.
2) Today’s strict privacy regulations require sensitive data, like passwords, to be protected. Failing to comply can result in fines.
3) Password security is one of the basic security features my clients expect from me.
4) If I know how to do it properly, my reputation will improve and my clients will trust me.

So, are legacy MD5 and SHA hashes secure? Short answer: No!

Back in the day, passwords were stored using an MD5 or SHA1 hash.
Like this: 
$𝘩𝘢𝘴𝘩 = 𝘮𝘥5($𝘱𝘢𝘴𝘴𝘸𝘰𝘳𝘥);

However, this technique is not safe enough. For two reasons:
1) MD5 and SHA algorithms 𝐚𝐫𝐞 𝐭𝐨𝐨 𝐰𝐞𝐚𝐤 for today’s computational power.
2) Simple, not-salted hashes are vulnerable to “𝐫𝐚𝐢𝐧𝐛𝐨𝐰 𝐭𝐚𝐛𝐥𝐞𝐬” and dictionary attacks.

If an attacker steals an MD5 or SHA hash, he or she can easily find out the original password too. In other words, these hashes are almost as insecure as plain text passwords.

The solution is to use a PHP 𝐬𝐞𝐜𝐮𝐫𝐞 𝐡𝐚𝐬𝐡𝐢𝐧𝐠 𝐟𝐮𝐧𝐜𝐭𝐢𝐨𝐧:
$𝘩𝘢𝘴𝘩 = 𝘱𝘢𝘴𝘴𝘸𝘰𝘳𝘥_𝘩𝘢𝘴𝘩($𝘱𝘢𝘴𝘴𝘸𝘰𝘳𝘥, 𝘗𝘈𝘚𝘚𝘞𝘖𝘙𝘋_𝘉𝘊𝘙𝘠𝘗𝘛);

The password_hash() function creates a secure hash of your password. The result hash from password_hash() is secure because:
1) It uses a 𝐬𝐭𝐫𝐨𝐧𝐠 𝐡𝐚𝐬𝐡𝐢𝐧𝐠 𝐚𝐥𝐠𝐨𝐫𝐢𝐭𝐡𝐦.
2) It adds a 𝐫𝐚𝐧𝐝𝐨𝐦 𝐬𝐚𝐥𝐭 to prevent rainbow tables and dictionary attacks.

Once you have the password hash, you can save it directly in the database.

To verify the password provided by a remote user, you need to use the password_verify() function.

Important:
You cannot just compare two different hashes to see if they match.
The reason is that password_hash() creates 𝐬𝐚𝐥𝐭𝐞𝐝 𝐡𝐚𝐬𝐡𝐞𝐬.

Salted hashes include a random string, named “salt”, as a protection against rainbow tables and dictionary attacks. Therefore, every hash will be different even if the source password is the same.

Note:
password_verify() only works with hashes created by password_hash(). You cannot use it to check a password against a MD5 or SHA hash.

There are ways you can still add hash protection, but I may write about them a second time.

You can read more in the PHP manual