Introduction

This guide explains the use of patterns when creating passwords, and provides some example scripts to make this easy to do.

The Use Of Patterns In Passwords

Passwords will be inevitable for some time to come, so choosing a safe password is essential. Most of us, however, have numerous passwords, and truly random passwords are difficult to remember. As a result, we either write them down or reuse the same ones over and over - neither of which is a good idea from a security standpoint.

Some time ago a study was done determining a pattern for creating fairly good passwords that are easy to remember. This has been tested with users of all ages and backgrounds, and it really works.

A Pattern To Remember

The key is a structured pattern. Patterns are easy for us to remember. This particular pattern contains the following pieces:

  1. A pronounceable piece.
  2. Some number of numbers and symbols.
  3. A pronounceable piece.

We are going to use the following pattern in detail:

  1. An upper or lower case consonant.
  2. A lower case vowel.
  3. A lower case consonant.
  4. Sometimes another lower case vowel or consonant.
  5. Between 1 and 4 groupings of:
    • A number.
    • The shift of that number.
  6. An upper or lower case consonant (if the first letter of the password is not a capital letter, force this letter to be a capital).
  7. A lower case vowel.
  8. A lower case consonant.
  9. Sometimes another lower case vowel or consonant.

Example Scripts

An Example In PERL

The following PERL script implements this pattern:

# generate fairly good rememberable passwords

srand(time() ^ ($$ + $$ << 21));

$howMany = 20;

$sym = "~`!@#$%^&*()-_+=,.<>";
$numb = "123567890";
$symcornum = "!@#%^&*()";
$numbsym = "1234567890~`!@#$%^&*()-_+=,.<>";
$lnumb = length($numb);
$lsym = length($sym);
$lnumbsym = length($numbsym);
$lsymcornum = length($symcornum);

$bothcons = "BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxz";
$upcons = "BCDFGHJKLMNPQRSTVWXYZ";
$lowcons = "bcdfghjklmnpqrstvwxz";
$lowvowel = "aeiou";
$convow = "bcdfghjklmnpqrstvwxyzaeiou";
$lbothcons = length($bothcons);
$llowcons = length($lowcons);
$llowvowel = length($lowvowel);
$lupcons = length($upcons);
$lconvow = length($convow);

for ($j=0; $j<=$howMany; $j++) {

   $pass = "";

# generate the first pronounceable part

   $pass .= substr($bothcons,int(rand($lbothcons)),1);
   $pass .= substr($lowvowel,int(rand($llowvowel)),1);
   $pass .= substr($lowcons,int(rand($llowcons)),1);
   if (rand > 0.5) {
      $pass .= substr($convow,int(rand($lconvow)),1);
   }

# generate some number symbol sets

   $numind = int(rand($lnumb));
   $pass .= substr($numb,$numind,1);
   $pass .= substr($symcornum,$numind,1);

   if (rand > 0.5) {
   $numind = int(rand($lnumb));
   $pass .= substr($numb,$numind,1);
   $pass .= substr($symcornum,$numind,1);
   }

   if (rand > 0.5) {
   $numind = int(rand($lnumb));
   $pass .= substr($numb,$numind,1);
   $pass .= substr($symcornum,$numind,1);
   }

   if (rand > 0.5) {
   $numind = int(rand($lnumb));
   $pass .= substr($numb,$numind,1);
   $pass .= substr($symcornum,$numind,1);
   }

# generate the end pronounceable part

   if ($pass =~ /[A-Z]/) {
      $pass .= substr($bothcons,int(rand($lbothcons)),1);
   }
   else {

      $pass .= substr($upcons,int(rand($lupcons)),1);
   }
   $pass .= substr($lowvowel,int(rand($llowvowel)),1);
   $pass .= substr($lowcons,int(rand($llowcons)),1);
   if (rand > 0.5) {
      $pass .= substr($convow,int(rand($lconvow)),1);
   }

   print "$pass";
   print "\n";
}
# Be sure to end the last line with an end of line.
print "\n";

An example of the output:

Voz3#9(Xuk
Lor8*1!susj
Sif8*9(8*2@Bux
Suzn2@0)zif
wohm0)2@2@Juk
fan1!7&Kuma
sub9(8*2@1!Cur
zeky5%1!Modx
Cogc9(0)Pir
Gixt2@1!kop
vewk8*0)Job
gehc3#Cak
Dizx5%8*6^Xebg
Reby3#6^Nez
Gilf1!8*tovc
Yoj6^9(liz
xos5%6^1!Vowp
sup5%2@Xol
reni5%8*Tejw
foj7&0)5%Tug
Piw7&5%8*moc

Another Example In PERL

This version of the PERL script prints each part out separately:

# generate fairly good rememberable passwords

srand(time() ^ ($$ + $$ << 21));

$howMany = 10;

$sym = "~`!@#$%^&*()-_+=,.<>";
$numb = "123567890";
$symcornum = "!@#%^&*()";
$numbsym = "1234567890~`!@#$%^&*()-_+=,.<>";
$lnumb = length($numb);
$lsym = length($sym);
$lnumbsym = length($numbsym);
$lsymcornum = length($symcornum);

$bothcons = "BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxz";
$upcons = "BCDFGHJKLMNPQRSTVWXYZ";
$lowcons = "bcdfghjklmnpqrstvwxz";
$lowvowel = "aeiou";
$convow = "bcdfghjklmnpqrstvwxyzaeiou";
$lbothcons = length($bothcons);
$llowcons = length($lowcons);
$llowvowel = length($lowvowel);
$lupcons = length($upcons);
$lconvow = length($convow);


   print "\n";
   print "Pick a first part...\n";
   print "\n";

for ($j=0; $j<=$howMany; $j++) {

   $firstpart = "";

# generate the first pronounceable part

   $firstpart .= substr($bothcons,int(rand($lbothcons)),1);
   $firstpart .= substr($lowvowel,int(rand($llowvowel)),1);
   $firstpart .= substr($lowcons,int(rand($llowcons)),1);
   if (rand > 0.5) {
      $firstpart .= substr($convow,int(rand($lconvow)),1);
   }
   print "$firstpart";
   print "\n";

}

   print "\n";
   print "Pick a middle part...\n";
   print "\n";


for ($j=0; $j<=$howMany; $j++) {

   $middlepart = "";
   $middlepartnosym = "";

# generate some number symbol sets

   $numind = int(rand($lnumb));
   $middlepart .= substr($numb,$numind,1);
   $middlepartnosym .= substr($numb,$numind,1);
   $middlepart .= substr($symcornum,$numind,1);

   if (rand > 0.5) {
   $numind = int(rand($lnumb));
   $middlepart .= substr($numb,$numind,1);
   $middlepartnosym .= substr($numb,$numind,1);
   $middlepart .= substr($symcornum,$numind,1);
   }

   if (rand > 0.5) {
   $numind = int(rand($lnumb));
   $middlepart .= substr($numb,$numind,1);
   $middlepartnosym .= substr($numb,$numind,1);
   $middlepart .= substr($symcornum,$numind,1);
   }

   if (rand > 0.5) {
   $numind = int(rand($lnumb));
   $middlepart .= substr($numb,$numind,1);
   $middlepartnosym .= substr($numb,$numind,1);
   $middlepart .= substr($symcornum,$numind,1);
   }

   print "$middlepart ($middlepartnosym)";
   print "\n";

}

   print "\n";
   print "Pick an end part...\n";
   print "\n";

for ($j=0; $j<=$howMany; $j++) {

   $endpart = "";

# generate the end pronounceable part

   if ($firstpart =~ /[A-Z]/) {
      $endpart .= substr($bothcons,int(rand($lbothcons)),1);
   }
   else {

      $endpart .= substr($upcons,int(rand($lupcons)),1);
   }
   $endpart .= substr($lowvowel,int(rand($llowvowel)),1);
   $endpart .= substr($lowcons,int(rand($llowcons)),1);
   if (rand > 0.5) {
      $endpart .= substr($convow,int(rand($lconvow)),1);
   }

   print "$endpart";
   print "\n";
}

   print "\n";
   print "For example: $firstpart$middlepart$endpart";
   print "\n";

# Be sure to end the last line with an end of line.
print "\n";

An example of the output:

Pick a first part...

Feq
Lazg
xand
Sev
Lan
Sajm
Yeq
ticp
Jupv
Wodz
Guhd

Pick a middle part...

8*2@1! (821)
0)5%0) (050)
0)6^1! (061)
3#5% (35)
6^0) (60)
5%9( (59)
6^2@ (62)
0)0) (00)
8*9(1! (891)
0)7&8* (078)
7&3#2@ (732)

Pick an end part...

Qufe
baz
Mane
qek
sin
Hebc
cedk
Dawq
Juqt
bid
pej

For example: Guhd7&3#2@pej

The Same Scripts In PHP

The following are versions of the above scripts but implemented in PHP and suitable for use on a web site:

Coming soon...

Varying The Pattern

The passwords created using this pattern are still fairly random, but are much easier to remember. A fairly good password that is easy to remember, even if you have several, is better than a truly random password that is inevitably written down.

You can also vary the pattern. Instead of a number and the shift of that number, use a number and the shift of the number to the left or right for each pair - just as long as you are consistent, and know what the pattern is.

For example:

1!2@3#

Or:

2!3@4#

Or:

2#3$4%

The scripts above are easily tweaked to implement these variations.

Security

The strength of these generated passwords and resistance to cracking comes from two factors - the pseudo random nature of the letter combinations and the variable length of the password.

See Also

  • StrongPasswords - A guide demonstrating the generation of strong passwords with applications available to Ubuntu.

GeneratingRememberablePasswords (last edited 2009-08-14 21:14:59 by rocket2dmn)