Generating strong passwords is a fundamental element of application security. A strong password should be long and contain a combination of different character types.
An outdated approach, often seen in old tutorials, used functions like rand()
and srand()
. These are not considered secure enough for cryptographic tasks. Here is a modern and secure solution for generating passwords in PHP.
The Modern Function: generateStrongPassword
This new function uses random_int()
, which is designed in PHP to generate cryptographically secure random integers. It is also much more flexible and readable.
/**
* Generates a secure password.
*
* @param int $length Desired password length.
* @param bool $includeDigits Include digits.
* @param bool $includeUppercase Include uppercase letters.
* @param bool $includeLowercase Include lowercase letters.
* @param bool $includeSymbols Include symbols.
* @return string The generated password.
* @throws \Exception If secure random number generation fails.
*/
function generateStrongPassword(
int $length = 12,
bool $includeDigits = true,
bool $includeUppercase = true,
bool $includeLowercase = true,
bool $includeSymbols = true
): string {
$characterSets = [];
if ($includeDigits) {
$characterSets[] = '0123456789';
}
if ($includeUppercase) {
$characterSets[] = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
}
if ($includeLowercase) {
$characterSets[] = 'abcdefghijklmnopqrstuvwxyz';
}
if ($includeSymbols) {
// You can customize this list of symbols
$characterSets[] = '!@#$%^&*()_+-=[]{}|';
}
if (empty($characterSets)) {
throw new \InvalidArgumentException('At least one character set must be selected.');
}
$password = '';
$allCharacters = implode('', $characterSets);
// Guarantees at least one character from each requested set for robustness
foreach ($characterSets as $set) {
$password .= $set[random_int(0, strlen($set) - 1)];
}
// Completes the rest of the password
$remainingLength = $length - count($characterSets);
if ($remainingLength > 0) {
for ($i = 0; $i < $remainingLength; $i++) {
$password .= $allCharacters[random_int(0, strlen($allCharacters) - 1)];
}
}
// Shuffles the password so that the first characters are not predictable
return str_shuffle($password);
}
Why is this approach better?
- Increased Security:
random_int()
is designed for cryptographic needs, unlikerand()
which produces predictable numbers and should never be used for security. - Flexibility: Instead of an unintuitive
$strength
parameter, the new function uses explicit booleans ($includeDigits
,$includeUppercase
, etc.). This makes the code more readable and easier to use. - Guaranteed Robustness: The function ensures that if you request digits, uppercase letters, and symbols, the password will contain at least one character of each requested type, before completing the rest.
- Modern Code: The use of strict typing (
int
,bool
,string
) and exceptions makes the function more robust and integrable into modern projects.
Code Explanation
$characterSets
: An array that will contain the possible character strings (digits, uppercase, etc.) depending on the parameters.random_int(min, max)
: The cornerstone of our function. It generates a high-quality random number betweenmin
andmax
.- Character Set Guarantee: The first
foreach
loop iterates through the requested character sets and adds a random character from each set to the password. This prevents having a password that, by bad luck, would only contain lowercase letters when you had requested others. - Padding: The next
for
loop completes the password to the desired length by randomly drawing from the set of all allowed characters. str_shuffle()
: This last step is crucial. It shuffles the final character string to ensure that the first characters (those guaranteed by the first loop) do not follow a predictable order (e.g., always a digit, then an uppercase letter, etc.).
Usage Examples
// 16-character password with all character types (default)
echo generateStrongPassword(16);
// Possible result: j!6P@sWqK_zR{gE8
// Simple 8-character password, with only lowercase letters and digits
echo generateStrongPassword(8, true, false, true, false);
// Possible result: 4p7k1n9z
// 10-character password without symbols
echo generateStrongPassword(10, true, true, true, false);
// Possible result: 9aB4rT2zK1
By adopting this modern approach, you significantly improve the security of password generation in your PHP applications.