Create A Password Generator In PHP

Create A Password Generator In PHP

Generating strong, random passwords is an important security practice for anyone living in the 21st century, but especially for devs. So, we are going to walk through the process of building a simple PHP CLI tool for generating random passwords. And we are going to call this tool,cli-passwd-gen.

What Do We Need?

The basic concept of cli-passwd-gen is to create a random string of characters and then print the resulting string to the screen. Before getting started, we should consider the program requirements for cli-passwd-gen.

Program Requirements

  1. Capability to specify the length of the password

  2. Capability to specify character types (lowercase, uppercase, numbers, and/or special characters)

  3. The characters in the password should be random

  4. The generated password should output to the command line at the completion

  5. When executing the command, the user will need to specify values for the following required arguments:

    • -t, --types - Types of characters the user wants to include in the password.

      • There are only four valid values for this argument: 'l', 'u', 'n', 's'. Which represent: lowercase, uppercase, numbers, and/or special (for special characters).
    • -l, --length - Integer value denoting the number of characters the user wants to include in their password.

  6. We will also need to use the following built-in PHP functions:

    • getopt() - Parses command-line options and arguments into an array.

      • This will allow us to take in user input to customize the password.
    • isset() - Determines whether a variable has been set or not.

      • This will help us verify that the user has set the required options.
    • strpos() - Finds the position of the first occurrence of a substring in a string.

      • This allows us to determine the optional arguments that the user has selected.
    • exit() - Terminates the program and outputs a message to the screen.

      • We will use this when handling input validation errors.
    • pregmatch() - Finds a match for a specified regular expression.

      • We will use this to validate user input.
    • random_int() - Generates a cryptographically random integer.

      • This will help us select random characters for the password string.
    • strlen() - Gets the length of a string.

In a few lines of code, we will create a simple, but effective password generator that can be used to create strong and secure passwords on the fly.

1. Set Up The Command Line Interface

First, create a PHP file for this program. I'm going to name mine, cli-passwd-gen.php .

To set up the command line interface, we'll use PHP's built-in getopt() function. This function parses command line options and arguments and returns an associative array of the options and their values.

Here's an example of how we use getopt() to parse command line options at the beginning of the program:

<?php

// Parse the user's command and compare with these options
$options = getopt("l:t:", ["length:", "types:"]);

// Check if $options['l'] exists -- if so, assign it to $length
// Else, assign $options['length'] to $length
$length = isset($options['l']) ? (int)$options['l'] : (int)$options['length'];

$types = isset($options['t']) ? $options['t'] : $options['types'];

Defining Arguments And Assigning User Input

This code does two things:

  1. It defines arguments. In this case, length and types.

  2. It specifies how the program will identify what values the user has passed in for each of these arguments. Then, it assigns those values to corresponding variables.

  • -l or --length specifies the length of the password. The user passes in an integer value for $options['l'] or $options['length']. This will be assigned to $length.

  • -t or --types specifies the character types to include in the password. The user will pass in character value(s) for $options['t'] or $options['types']. Then, this will be assigned to $types.

    • There are only four values that can be passed in for -t, --types: 'l', 'u', 'n', and/or 's'. Which represent lowercase letters, uppercase letters, numbers, and special characters, respectively.

Let's look at an example. The user opens the terminal and runs the cli-passwd-gen program. If the user wants a password of length 12 with only lowercase and uppercase letters. So, their command would look like this:

php cli-passwd-gen.php --length 12 --types lu

The program is going to take the values that the user specified for each of the options and assign the values to the corresponding variables. See in the code below how $length is assigned 12 and $types is assigned 'lu':

$length = isset($options['l']) ? (int)$options['l'] : (int)$options['length'];
// $length = 12;

$types = isset($options['t']) ? $options['t'] : $options['types'];
// $types = 'lu';

2. Validate Arguments & Handle Errors

Next, we'll validate the command line arguments and handle any potential errors. For the --length, -l argument, we'll check that it's a positive integer. For the --types, -t argument, we'll check that it's a string containing only the characters l, u, n, and/or s.

If either one of these statements is false (input does not pass validation), which will cause the program to exit.

if (!$length || $length <= 0) {
    exit("Error: Password length must be a positive integer\n");
}

if (!$types || !preg_match('/^[luns]*$/', $types)) {
    exit("Error: Password types must be a string containing only 'l', 'u', 'n', and/or 's'\n");
}

We use preg_match() to check that the types string contains only the allowed characters.

3. Filter User Input

Now, the program is taking the options that the user typed in the command line and determining what characters should be used to generate the password:

$lowercase = 'abcdefghijklmnopqrstuvwxyz';
$uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$numbers = '0123456789';
$special = '!@#$%^&*()_+-={}[];\',./<>?:"|\\';
$chars = '';

// Find the first occurrence of each substring (l, u, n, or s) within $types
if (strpos($types, 'l') !== false) {
    $chars .= $lowercase;
}

if (strpos($types, 'u') !== false) {
    $chars .= $uppercase;
}

if (strpos($types, 'n') !== false) {
    $chars .= $numbers;
}

if (strpos($types, 's') !== false) {
    $chars .= $special;
}

But, let's break this down a little bit.

Specify Character Types To Use In The Password

We begin by defining several variables ($lowercase, $uppercase, $numbers, and $special). These are the character types that are available for the user to choose for their password.

$lowercase = 'abcdefghijklmnopqrstuvwxyz';
$uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$numbers = '0123456789';
$special = '!@#$%^&*()_+-={}[];\',./<>?:"|\\';

The final variable definition, $chars, is an empty string. The value of each character type ($lowercase, $uppercase, $numbers, and/or $special) that is chosen by the user will be concatenated to this string.

$chars = '';

The $chars variable will determine which characters the program should use when randomly generating a password string.

Check User Input

The collection of if statements below the variable definitions will sift through the user's input to determine which options were selected ('l', 'u', 'n', or 's').

if (strpos($types, 'l') !== false) {
    $chars .= $lowercase;
}

if (strpos($types, 'u') !== false) {
    $chars .= $uppercase;
}

if (strpos($types, 'n') !== false) {
    $chars .= $numbers;
}

if (strpos($types, 's') !== false) {
    $chars .= $special;
}

If one of these arguments were specified by the user (e.g., --types ln), then that set of characters (in this case,$lowercase and $numbers) will be concatenated to the $chars string. Which will be used to generate a randomized password.

Continuing from the last example (--types ln), the program will check if the user's input includedl for the -t, --types argument. Since l was specified by the user, this statement is true. So, the entire $lowercase string will be concatenated to $chars.

if (strpos($types, 'l') !== false) {
    $chars .= $lowercase;
}
# $chars = 'abcdefghijklmnopqrstuvwxyz'

When the program receives input from the user that specifies that the types of characters used should be lowercase letters l and numbers n, the string values stored in the $lowercase and $numbers variables are concatenated to $chars.

php cli-passwd-gen.php --length 12 --types ln

So, our $chars string will be equivalent to this:

$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';

Now that the user has specified parameters for the password, it's time to put all of this information together and generate a random string.

4. Generate The Password

We'll use PHP's random_int() function to generate random numbers, and use those numbers to select characters from the user-specified character types, $chars.

$password = '';
for ($i = 0; $i < $length; $i++) {
    $index = random_int(0, strlen($chars) - 1);
    $password .= $chars[$index];
}

echo $password . "\n";

Here, we are using a for-loop to add random characters to the password string. Notice that strlen() takes the size of $chars to determine a random integer.

$index = random_int(0, strlen($chars) - 1);

This will serve as the index to select a value from the $chars string and concatenate it to the password.

$password .= $chars[$index];

This loop continues until the user's desired password $length is met. At this point, the echo statement causes the password string to be printed to the terminal.

5. Test The Program

Navigate to the directory where you have saved the cli-passwd-gen program file. Then run the following command with your chosen file name:

$ php cli-passwd-gen.php --length 12 --types lun
# output: Tc7s1b4Lw3fV

To test the program, you can run it with various combinations of options and verify that the generated passwords meet the requirements.

$ php cli-passwd-gen.php --length 8 --types l
# output: xhzzjmli
$ php cli-passwd-gen.php --length 10 --types u
# output: LPKNWVRSDI
$ php cli-passwd-gen.php --length 6 --types ns
# output: @*&#$^
$ php cli-passwd-gen.php --length 5 --types luns
# output: g%u6K

Conclusion

In this project, we learned how to create a command-line password generator using PHP. We put basic concepts of password generation into practice. And also gained experience working with PHP functions, such as getopt() and strpos(), among others. In addition, we learned how to generate random characters and validate user input, which are important skills in any programming project.

By combining these lessons, we were able to create a simple but effective tool for generating strong passwords on the command line.