Please wait

Password Hashing

One of the most critical steps you can take to secure an application is hashing passwords. Hashing is like taking a secret message (for example, a password) and passing it through a special machine that turns it into a complex code. Once it's coded, you can't easily turn it back into the original message.

Imagine you have a blender (the hashing function) and a piece of fruit (the password). You put the fruit in the blender and turn it on. The fruit gets mashed into a smoothie (the hash), and there's no way to un-blend it to find out exactly what fruit it was.

In PHP, hashing is used to secure passwords. When a user creates or enters a password, it's turned into a "smoothie" using a function like password_hash(). The smoothie (hash) is then stored in the database.

When the user tries to log in, the password they enter is turned into a smoothie again, and if it matches the smoothie in the database, they can access their account. If anyone looks in the database, they only see smoothies, not the original passwords, so the information stays safe.

Hashing a Password

Hashing a password in PHP is a straightforward process, and the password_hash() function is specifically designed for this purpose. First, let's look at the function definition:

password_hash(string $password, string|int|null $algo, array $options = []): string

Parameters

  • $password: The user's plain-text password that you want to hash.
  • $algo: This defines which hashing algorithm to use. PASSWORD_DEFAULT is generally a good choice, as it uses the currently recommended algorithm, which may change over time as newer, more secure algorithms are developed.
  • $options: This is an associative array of options that you can use to customize the hash. For example:
    • cost: Controls the computational cost of the hash, making it more resource-intensive to crack. A higher cost means more security but slower processing.
    • salt: Previously used to provide a salt for the hash, but it's been deprecated since PHP 7.0.0. Modern algorithms generate their own salt.

Here's how you can use this function:

$password = 'mypassword'; // The original password
$hashed_password = password_hash($password, PASSWORD_DEFAULT); // Hashing the password
 
echo $hashed_password;

The following gets outputted:

$2y$10$.TtL8HcnxpelrJdYoVQSuOHzBH5gW9Zkwy1D8eniux09ne3uC9J86

By hashing passwords with the password_hash() function, you ensure that the stored passwords in your database are securely obfuscated, making it much more difficult for malicious actors to retrieve the original passwords.

Algorithms

The second argument of the password_hash() function is the algorithm for hashing the password. A hashing algorithm is a function that takes an input (or "message") and returns a fixed-length string of bytes.

The output, or hash value, should be the same length regardless of the length of the input. The idea is that it's computationally infeasible to generate the same hash output from two different inputs, and it should be extremely difficult to reverse the process to reveal the original input.

The PASSWORD_DEFAULT constant uses bcrypt. bcrypt is a popular password hashing algorithm designed to build a cryptographically secure hash. It takes the password and a salt (random data) and combines them in a way that is slow and resource-intensive. This "slowness" is a feature, as it makes brute-force attacks more difficult. bcrypt is widely used and considered robust against common attacks, including rainbow tables and brute force, thanks to its adaptive cost.

When choosing a password hashing algorithm in PHP, using PASSWORD_DEFAULT with password_hash() is generally the safest bet, as it will use the most robust algorithm currently supported (as of PHP 7.4, that's bcrypt).

Other algorithms include:

AlgorithmPHP ConstantDescription
bcryptPASSWORD_BCRYPTA widely-used algorithm that's slow and resource-intensive, making brute-force attacks more difficult. Recommended for passwords.
Argon2iPASSWORD_ARGON2IA modern algorithm optimized for resistance against side-channel attacks. Good for password hashing.
Argon2idPASSWORD_ARGON2IDA hybrid of Argon2i and Argon2d. Offers a high level of security for password hashing.

Verifying a Password

Once you've hashed the password, you will want to verify the passwords. Verifying a password in PHP can be done using the password_verify() function, which checks a plaintext password against a hashed password to see if they match. It is a simple and secure way to handle password validation, especially when used in conjunction with the password_hash function.

Here's the definition for the password_verify() function:

password_verify(string $password, string $hash): bool

Parameters

  • $password: The user-provided password (in plaintext) that you want to verify.
  • $hash: The stored hash against which the password will be verified. This is the hashed version of the password that you have stored in your database or other secure storage, obtained using password_hash.

The function returns a boolean value. true if the password and hash match. false if the password and hash do not match.

Here's how you would use the function.

$hashed_password = password_hash('secret-password', PASSWORD_DEFAULT);
$user_input_password = 'secret-password';
 
if (password_verify($user_input_password, $hashed_password)) {
  echo 'Password is valid!';
} else {
  echo 'Invalid password.';
}

In the example above, password_hash() is used to create a hash of the password, and then password_verify() is used to check the user-inputted password against the stored hash. If the passwords match, the function returns true, and if they don't, it returns false.

This function abstracts the complexities of secure password verification, so it's highly recommended to use it rather than attempting to manually compare hashed passwords.

Key Takeaways

  • Hashing is the process of converting a plaintext password into a fixed-size string of bytes. It ensures that the actual password is not stored, making it more secure.
  • Algorithms like bcrypt, Argon2i, and Argon2id are preferred for password hashing. They offer a good balance of security and performance. 0 PHP provides the password_hash() function, making it easy to hash passwords with a selected algorithm. It also handles salting.
  • The password_verify() function is used to compare a plaintext password with a hashed version, securely handling the comparison process.
  • Avoid using outdated algorithms like MD5 or SHA-256 for password hashing, as they lack specific features required for securely handling passwords.
  • Hashed passwords should be stored securely in a database. They are used for future comparisons when a user tries to log in.

Comments

Please read this before commenting