The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

CtrlO::Crypt::XkcdPassword - Yet another xkcd style password generator

VERSION

version 1.011

SYNOPSIS

  use CtrlO::Crypt::XkcdPassword;
  my $password_generator = CtrlO::Crypt::XkcdPassword->new;

  say $password_generator->xkcd;
  # LimousineAllegeClergymanEconomic

  say $password_generator->xkcd( words => 3 );
  # ObservantFiresideMacho

  say $password_generator->xkcd( words => 3, digits => 3 );
  # PowerfulSpreadScarf645

  # Use custom word list
  CtrlO::Crypt::XkcdPassword->new(
    wordlist => '/path/to/wordlist'
  );
  CtrlO::Crypt::XkcdPassword->new(
    wordlist => 'Some::Wordlist::From::CPAN'
  );

  # Use another source of randomness (aka entropy)
  CtrlO::Crypt::XkcdPassword->new(
    entropy => Data::Entropy::Source->new( ... );
  );

DESCRIPTION

CtrlO::Crypt::XkcdPassword generates a random password using the algorithm suggested in https://xkcd.com/936/: It selects 4 words from a curated list of words and combines them into a hopefully easy to remember password (actually a passphrase, but we're all trying to get things done, so who cares..).

See this explaination for detailed information on the security of passwords generated from a known word list.

But https://xkcd.com/927/ also applies to this module, as there are already a lot of modules on CPAN implementing https://xkcd.com/936/. We still wrote a new one, mainly because we wanted to use a strong source of entropy and a fine-tuned word list.

METHODS

new

  my $pw_generator = CtrlO::Crypt::XkcdPassword->new;

Initialize a new object. Uses CtrlO::Crypt::XkcdPassword::Wordlist::en_gb as a word list per default. The default entropy is based on Crypt::URandom, i.e. /dev/urandom and should be random enough (at least more random than plain old rand()).

If you want / need to supply another source of entropy, you can do so by setting up an instance of Data::Entropy::Source and passing it to new as entropy.

  my $pw_generator = CtrlO::Crypt::XkcdPassword->new(
      entropy => Data::Entropy::Source->new( ... )
  );

To use one of the included language-specific word lists, do:

  my $pw_generator = CtrlO::Crypt::XkcdPassword->new(
      language => 'en-GB',
  );

Available languages are:

  • en-GB

You can also provide your own custom word list, either in a file:

  my $pw_generator = CtrlO::Crypt::XkcdPassword->new(
      wordlist => '/path/to/file'
  );

Or in a module:

  my $pw_generator = CtrlO::Crypt::XkcdPassword->new(
      wordlist => 'My::Wordlist'
  );

See "DEFINING CUSTOM WORD LISTS" for more info.

xkcd

  my $pw = $pw_generator->xkcd;
  my $pw = $pw_generator->xkcd( words  => 3 );
  my $pw = $pw_generator->xkcd( digits => 2 );

Generate a random, xkcd-style password.

Per default will return 4 randomly chosen words from the word list, each word's first letter turned to upper case, and concatenated together into one string:

  $pw_generator->xkcd;
  # CorrectHorseBatteryStaple

You can get a different number of words by passing in words. But remember that anything smaller than 3 will probably make for rather poor passwords, and anything bigger than 7 will be hard to remember.

You can also pass in digits to append a random number consisting of digits digits to the password:

  $pw_generator->xkcd( words => 3, digits => 2 );
  # StapleBatteryCorrect75

DEFINING CUSTOM WORD LISTS

Please note that language is only supported for the default word list included in this distribution.

in a plain file

Put your word list into a plain file, one line per word. Install this file somewhere on your system. You can now use your word list like this:

  CtrlO::Crypt::XkcdPassword->new(
    wordlist => '/path/to/wordlist'
  );

in a Perl module using the Wordlist API

Perlancar came up with a unified API for various word list modules, implemented in Wordlist. Pack your list into a module adhering to this API, install the module, and load your word list:

  CtrlO::Crypt::XkcdPassword->new(
    wordlist => 'Your::Cool::Wordlist'
  );

You can check out CtrlO::Crypt::XkcdPassword::Wordlist::en_gb (included in this distribution) for an example. But it's really quite simple: Just subclass Wordlist and put your list of words into the __DATA__ section of the module, one line per word.

in a Perl module using the Crypt::Diceware API

David Golden uses a different API in his Crypt::Diceware module, which inspired the design of CtrlO::Crypt::XkcdPassword. To use one of those word lists, use:

  CtrlO::Crypt::XkcdPassword->new(
    wordlist => 'Crypt::Diceware::Wordlist::Common'
  );

(yes, this looks just like when using Wordlist. We inspect the wordlist module and try to figure out what kind of API you're using)

To create a module using the Crypt::Diceware wordlist API, just create a package containing a public array @Words containing your word list.

INCLUDED WORD LISTS

This distribution comes with a hand-crafted word list CtrlO::Crypt::XkcdPassword::Wordlist::en_gb and three word lists provided by EFF: CtrlO::Crypt::XkcdPassword::Wordlist::eff_large, CtrlO::Crypt::XkcdPassword::Wordlist::eff_short_1 and CtrlO::Crypt::XkcdPassword::Wordlist::eff_short_2_0.

WRAPPER SCRIPT

This distributions includes a simple wrapper script, pwgen-xkcd.pl.

RUNNING FROM GIT

This is not the recommended way to install / use this module. But it's handy if you want to submit a patch or play around with the code prior to a proper installation.

Carton

  git clone git@github.com:domm/CtrlO-Crypt-XkcdPassword.git
  carton install
  carton exec perl -Ilib -MCtrlO::Crypt::XkcdPassword -E 'say CtrlO::Crypt::XkcdPassword->new->xkcd'

cpanm & local::lib

  git clone git@github.com:domm/CtrlO-Crypt-XkcdPassword.git
  cpanm -L local --installdeps .
  perl -Mlocal::lib=local -Ilib -MCtrlO::Crypt::XkcdPassword -E 'say CtrlO::Crypt::XkcdPassword->new->xkcd'

SEE ALSO

Inspired by https://xkcd.com/936/ and https://xkcd.com/927/.

There are a lot of similar modules on CPAN, so we just point you to Neil Bower's comparison of CPAN modules for generating passwords.

But why did we write yet another module?

  • Good entropy

    Most of the password generating modules just use rand(), which "is not cryptographically secure" (according to perldoc). CtrlO::Crypt::XkcdPassword uses Crypt::URandom via Data::Entropy, which provides good entropy while still being portable.

  • Good word list

    While Crypt::Diceware has good entropy, we did not like its word lists. Of course we could have just provided a word list better suited to our needs, but we wanted it to be very easy to generate xkcd-style passwords.

  • Easy API

    my $pwd = CtrlO::Crypt::XkcdPassword->new->xkcd returns 4 words starting with an uppercase letter as a string, which is our main use case. Nevertheless, the API also allows for more or fewer words, or even some digits.

  • Fork save

  • https://xkcd.com/927/

THANKS

AUTHOR

Thomas Klausner <domm@plix.at>

COPYRIGHT AND LICENSE

This software is copyright (c) 2018 - 2021 by Thomas Klausner.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.