I’ve just released version two of the XKPasswd perl module, the module that powers the www.xkpasswd.net website. At the moment, only the module has been updated, not the website. It’s going to take me a few months to make all the changes I want to on that site. In the mean time you, can use the module directly. The prerequisites are that you have a computer with Perl and GIT installed, and a plain text editor (no difficult on Linux or Mac).

Getting Setup

On OS X

OS X ships with Perl installed as standard, so all you need is GIT and a plain text editor.

You have two options for installing GIT:

  1. Install the Xcode Command line Developer Tools as described here (recommended)
  2. Install just GIT as described here

For the text editor you can use the built-in TextEdit app (in the Applications folder), but there are two caveats:

  1. You must use it in plain-text mode (Format->Make Plain Text)
  2. You must disable Smart Quote and Smart Dashes. You can do this by un-checking the relevant checkboxes at the bottom of the New Document tab in TextEdit’s preferences (as shown below), and then creating a new document.

TextEdit Settings

You may prefer to use a more feature complete code editor, if so, I can recommend Smultron.

On Linux

Just about every Linux distro ships with Perl installed as standard, and you should be able to install GIT via just about any Linux distro’s default package manager.

On Windows

All this stuff can be done on Windows, but not as easily. I’m afraid I’m going to have to leave it as an exercise for the reader to figure out the best way to play around with this on Windows. My gut feeling is the answer is probably to use Cygwin.

Installing the XKPasswd 2 Perl Module (from GitHub)

Since the module is open source, I’ve chosen to host it on GitHub. To install it on a Unix/Linux/OS X system my recommendation is to open a Terminal window and enter the following commands (you must be an admin user, and the password requested is from sudo not GitHub, and is the password you use to log in to your computer):

cd /usr/local/
sudo git clone https://github.com/bbusschots/xkpasswd.pm.git

That’s it! You now have the latest version of the module installed. The two important components are the module itself located at /usr/local/xkpasswd.pm/XKPasswd.pm, and a sample dictionary located at /usr/local/xkpasswd.pm/XKPasswd.pm/sample_dict.txt.

In future you can update your copy to the latest version with these simple commands:

cd /usr/local/xkpasswd.pm
sudo git fetch

Creating a Basic Password Generation Script

The XKPasswd library comes with pre-defined presets. You’ll find a full list with a sample password in the presets section of the documentation.

For our first and simplest example, we’ll use the preset APPLEID, which generates passwords that comply with Apple’s very strict list of password requirements.

Using your chosen plain text editor, create a new file with the following content:

#!/usr/bin/perl
use lib '/usr/local/xkpasswd.pm/';
use XKPasswd;
my $password_generator = XKPasswd->new('/usr/local/xkpasswd.pm/sample_dict.txt', 'APPLEID');
print $password_generator->password()."\n";

Aside: to easily copy and paste out of the code areas on this blog, click the plain-text button in the heading of the code section to remove the formatting and line numbers before selecting the content for copying.

The first line is the so-called shebang line, and is there to tell the OS that this is a Perl script.

The next two lines import the XKPasswd module, the first tells Perl to use the location we installed the module to (/usr/local/xkpasswd.pm/) as a library folder, the second tells Perl to load the XKPasswd module.

The fourth line creates (or instantiates in programmer speak) an XKPasswd password generator object. The constructor is passed two pieces of information, the location of the dictionary file that should be used when generating the passwords, and the preset to be used.

Finally, the fifth line uses the instantiated object to generate and password, and then prints it.

Save this file into a folder of your choice with the name xkpasswd.pl. Next, open a Terminal and change to the same directory you saved the file to (Mac users can open the folder in the Finder, then open a Terminal window, type cd and a space, then drag and drop in the proxy icon from the top of the Finder window and hit enter on the Terminal).

Once in the correct folder in the Terminal we first need to make our script executable with:

chmod 755 xkpasswd.pl

And then we can run it with:

./xkpasswd.pl

Customising the Configuration

The pre-defined presets are simply shortcuts, they actually specify a much more detailed configuration. An XKPasswd configuration consists of a set of named keys with values. I’ve tried the make the names at least fairly self-explanatory, but you’ll find a full list of keys with a description of what they do in the Configuration Hashrefs section of the documentation.

A good way to get started is to look under the hood of the preset that most closely matches your desired outcome (again, we’ll be assuming APPLEID in our examples). To do this insert the following line of code above the last line (the one starting print):

print $password_generator->status()."\n";

Now when you run the script a whole bunch of status information will be printed out before the randomly generated password. The section of interest is the section starting *CONFIG*. This shows the values of all the configuration keys in use by the preset. It will look like:

*CONFIG*
case_transform: 'RANDOM'
character_substitutions: {}
num_words: '3'
padding_character: 'RANDOM'
padding_characters_after: '1'
padding_characters_before: '1'
padding_digits_after: '2'
padding_digits_before: '2'
padding_type: 'FIXED'
random_function: XKPasswd::basic_random_generator
random_increment: '12'
separator_alphabet: [',', '-', '.', ':']
separator_character: 'RANDOM'
symbol_alphabet: ['!', '&', '?', '@']
word_length_max: '7'
word_length_min: '5'

The XKPasswd module allows us to tweak presets by specifying a so-called overrides hashref. This set of overrides can be passed as a third argument to the constructor. For example, imagine we like the APPLEID preset, but want to use four words rather than the default three. The num_words config key specifies the number of words to be used when generating a password, so we would like to change it from the default 3 to 4.

We can do this by replacing the line starting my $password_generator in our script with the line:

my $password_generator = XKPasswd->new('/usr/local/xkpasswd.pm/sample_dict.txt', 'APPLEID', {num_words => 4});

If you run the script now and look at the *CONFIG* section of the status output you’ll see the value of the num_words key specified in the preset has been overridden with your custom value.

We can use the same technique to make multiple changes. To add an extra padding character front and back we could also update the keys padding_characters_before and padding_characters_after to 2. To do this we could replace the same line of code with the following even longer version:

my $password_generator = XKPasswd->new('/usr/local/xkpasswd.pm/sample_dict.txt', 'APPLEID', {num_words => 4, padding_characters_before => 2, padding_characters_after => 2});

This works, but clearly this is getting very un-gainly. A much neater way to achieve this level of customisation is to assemble all your overrides into a variable, and then pass that variable into the constructor. The following six lines can replace the single line above to do the same thing in a much more readable way:

my $config_overrides = {
    num_words => 4,
    padding_characters_before => 2,
    padding_characters_after => 2
};
my $password_generator = XKPasswd->new('/usr/local/xkpasswd.pm/sample_dict.txt', 'APPLEID', $config_overrides);

The same technique can be used to specify as many overrides as desired. Please note that you have to use valid Perl syntax when doing this, or the script will not run. That means that when ever you are specifying a character (or string of characters) rather than a number, you have to quote it with single quotes. Also, for keys that require a list, you have to use square brackets. Finally, don’t forget the comma at the end of each key definition! Below is a sample override that adds two more key changes to illustrate the use of characters and lists:

my $config_overrides = {
    num_words => 4,
    padding_characters_before => 2,
    padding_characters_after => 2,
    case_transform => 'ALTERNATE',
    separator_alphabet => ['-', '.', ':']
};
my $password_generator = XKPasswd->new('/usr/local/xkpasswd.pm/sample_dict.txt', 'APPLEID', $config_overrides);

Aside: if you want to see what the low-entropy warning looks like, set num_words to 2 and run the script. You should see output something like:

WARNING - XKPasswd::_update_entropystats_cache(): loaded dictionary and config combination results in low minimum entropy for attacks assuming full knowledge (35, warning threshold is 52) at ./xkpasswd.pl line 19.

Once we’re happy with our customisations we can remove the line to print the status. For best-practices reasons we should also import some standard Perl libraries at the top of the script, and, we should add in some comments to explain what we’re doing to our future selves when we come back to edit the script in the future. After all that the final script should look like:

#!/usr/bin/perl

# import best-practice standard perl modules
use strict;
use warnings;

# import the XKPassed module
use lib '/usr/local/xkpasswd.pm/';
use XKPasswd;

# create an XKPasswd password generator object with out custom config
my $config_overrides = {
    num_words => 4,
    padding_characters_before => 2,
    padding_characters_after => 2,
    case_transform => 'ALTERNATE',
    separator_alphabet => ['-', '.', ':']
};
my $password_generator = XKPasswd->new('/usr/local/xkpasswd.pm/sample_dict.txt', 'APPLEID', $config_overrides);

# use our generator to create and random password and print it
print $password_generator->password()."\n";

This script will now generate passwords for us, but, to use it we either have to cd into the folder we saved it to, or invoke it with it’s full path, neither particularly user-friendly.

We could use a BASH alias to make this easier for ourselves by aliasing the full path to the script to a nice memorable name. For more details on aliasing see part 14 of the Taming the Terminal series.

Another option would be to copy the script into a folder that is contained within the default $PATH. You can see what folder are in your path by running:

echo $PATH

On just about every POSIX OS (Linux/Unix/OS X) the folder /usr/local/bin is in the path, so you could copy your script to that folder with the command:

sudo cp xkpasswd.pl /usr/local/bin

You could then run the script from anywhere with the command:

xkpasswd.pl

For more on the $PATH environment variable see part 13 of the Taming the Terminal series.

For OS X users there is a better option though – you can incorporate your script right into the OS X GUI, meaning you won’t need the Terminal to generate passwords. The key to this is Automator’s abilities to execute shell scripts and save workflows as OS X Services. I’ve written a separate post explaining how to create such an OS X Service with Automator.