How To: Generate (semi) User Friendly Passwords

Yesterday on Forrst, there was a great function to generate user friendly but still random passwords for users/clients. He did this by alternating between consonants and vowels, producing (more or less) pronounceable words. A few people brought up a concern about entropy, making them too vulnerable to a brute force attack. So I thought I would try to take the function and add some more entropy while still trying to keep the passwords as user friendly as possible. I added trailing numbers, and the possibility of doubling specific letters of our choosing. This way the letters will not always alternate between consonant and vowel, but by choosing which letters double up, we can keep the password fairly human readable. Note - We know that anytime you limit password content you increase the chance for brute force attacks, but by implementing just a few basic "login-side" security measures (even a simple hour lockout after 100 failed attempts) can essentially remove the possibility of brute force problems.
// The Project: Improve on Thomas Rambaud's great "friendly password" generator
// The Problem: Possibly susceptible to brute force attacks because passwords alternate vowels 
//      and consonants in order to be user friendly
// The Solution: Attempt to increase entropy by adding numbers and possible double letters 
//      based on English standards to still create a user friendly password 
 
// ** Updated 4-12-2011 to support the randomization of letter case and add a symbol
function friendly_names_2($length = 8){
   $pwd = "";
   $consonants = array('b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','z');
   $non_alphanum = '[email protected]#$&?';
   // Since we all know "y" is only sometimes a vowel, lets give it a chance
   $vowels = (rand(0, 10) % 2 == 0) ? array('a','e','i','o','u','y') : array('a','e','i','o','u');
   
   // The letters with the highest double letter frequency in English
   // according to letterfrequency.org
   $possible_doubles = array('s','e','t','f','l','m','o');
   
   for($i = 0; $i < $length; $i++){
       $letter_to_add = ($i % 2 == 0) ? $consonants[array_rand($consonants)] : $vowels[array_rand($vowels)]; 
       
       $pwd .= (rand(0,10) % 2 == 0) ? $letter_to_add : ucfirst($letter_to_add);
       
       // First, see if the letter is in our pool of possible double letters
       $is_double = in_array($letter_to_add, $possible_doubles);
       // Second, make sure it's not the first letter
       $is_started = (strlen($pwd) > 1) ? true : false;
       // Finally, an element of randomness
       $is_random = (rand(0, 10) % 2 == 0) ? true : false;
       // If we get all three, add the letter again
       if($is_random && $is_double && $is_started) $pwd .= $letter_to_add;
       
   }
   
   $number = rand(1, 99);
   
   $symbol = $non_alphanum[rand(0, strlen($non_alphanum)-1)];
   // Adding double letters will have increased our string length passed what
   // was asked, so cut it back down so it's under the max, including numbers
   
   $pwd = substr($pwd, 0, ($length - strlen($number)));
   
   return $number % 2 ? $pwd.$number.$symbol : $symbol.$pwd.$number ;  
}

echo friendly_names_2();  // ?CecAfe64
echo friendly_names_2();  // LOopee81#
echo friendly_names_2();  // ?booffa84
Small dog web development studio

View All Our Posts

Web application developers in western Washington, creating user centric web solutions for businesses of all shapes and sizes.

Our projects include ecommerce, event organization, user driven web applications and more.


Small Dog Studios, LLC. Small Dog Studios News