Skip to content

How to Strengthen the Password

Shield allows you to customize password-related settings to make your passwords more secure.

Minimum Password Length

The most important factor when it comes to passwords is the number of characters in the password. You can check password strength with Password Strength Testing Tool. Short passwords may be cracked in less than one day.

In Shield, you can set the users' minimum password length. The setting is $minimumPasswordLength in app/Config/Auth.php. The default value is 8 characters. It is the recommended minimum value by NIST. However, some organizations recommend 12 to 14 characters.

The longer the password, the stronger it is. Consider increasing the value.

Note

This checking works when you validate passwords with the strong_password[] validation rule. If you disable CompositionValidator (enabled by default) in $passwordValidators, this checking will not work.

Password Hashing Algorithm

You can change the password hashing algorithm by $hashAlgorithm in app/Config/Auth.php. The default value is PASSWORD_DEFAULT that is PASSWORD_BCRYPT at the time of writing.

PASSWORD_BCRYPT means to create new password hashes using the bcrypt algorithm.

You can use PASSWORD_ARGON2ID if your PHP has been compiled with Argon2 support.

PASSWORD_BCRYPT

PASSWORD_BCRYPT has one configuration $hashCost. The bigger the cost, hashed passwords will be the stronger.

You can find your appropriate cost with the following code:

<?php
/**
 * This code will benchmark your server to determine how high of a cost you can
 * afford. You want to set the highest cost that you can without slowing down
 * you server too much. 8-10 is a good baseline, and more is good if your servers
 * are fast enough. The code below aims for ≤ 50 milliseconds stretching time,
 * which is a good baseline for systems handling interactive logins.
 *
 * From: https://www.php.net/manual/en/function.password-hash.php#refsect1-function.password-hash-examples
 */
$timeTarget = 0.05; // 50 milliseconds

$cost = 8;
do {
    $cost++;
    $start = microtime(true);
    password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]);
    $end = microtime(true);
} while (($end - $start) < $timeTarget);

echo "Appropriate Cost Found: " . $cost;

Limitations

There are two limitations when you use PASSWORD_BCRYPT:

  1. the password will be truncated to a maximum length of 72 bytes.
  2. the password will be truncated at the first NULL byte (\0).
72 byte issue

If a user submits a password longer than 72 bytes, the validation error will occur. If this behavior is unacceptable, consider:

  1. change the hashing algorithm to PASSWORD_ARGON2ID. It does not have such a limitation.
NULL byte issue

This is because PASSWORD_BCRYPT is not binary-safe. Normal users cannot send NULL bytes in a password string, so this is not a problem in most cases.

But if this behavior is unacceptable, consider:

  1. adding a validation rule to prohibit NULL bytes or control codes.
  2. or change the hashing algorithm to PASSWORD_ARGON2ID. It is binary-safe.

PASSWORD_ARGON2ID

PASSWORD_ARGON2ID has three configuration $hashMemoryCost, $hashTimeCost, and $hashThreads.

If you use PASSWORD_ARGON2ID, you should use PHP's constants:

public int $hashMemoryCost = PASSWORD_ARGON2_DEFAULT_MEMORY_COST;

public int $hashTimeCost = PASSWORD_ARGON2_DEFAULT_TIME_COST;
public int $hashThreads  = PASSWORD_ARGON2_DEFAULT_THREADS;

Maximum Password Length

By default, Shield has the validation rules for maximum password length.

  • 72 bytes for PASSWORD_BCRYPT
  • 255 characters for others

You can customize the validation rule. See Customizing Validation Rules.

$supportOldDangerousPassword

In app/Config/Auth.php there is $supportOldDangerousPassword, which is a setting for using passwords stored in older versions of Shield that were vulnerable.

This setting is deprecated. If you have this setting set to true, you should change it to false as soon as possible, and remove old hashed password in your database.

Note

This setting will be removed in v1.0.0 official release.