The art of strong passwords.

If you are old enough to remember the movie, "War Games", You may recall a young Mathew Broderick who was eager to play a game from a remote computer. Unaware that the remote computer system was part of Norad's WOPR, or War Operation Plan Response computer. By doing a few hours of research he was able to easily guess the password (joshua) and gain access to the one machine that could cause World War Three. While hollywood always takes things to a whole new level of far-fetched,

These are not far off from security breaches of today. Good web security begins by forming good habits. But old habits are hard to break. One of which are good passwords. You have to be living in a cave or under a rock to not have to know and remember at least one password. And with more sites requiring registration (including this one), you may have to be able to recall dozens of passwords to access these systems. Having a "bad" password could make it easier for someone to crack the site or account by using an easily guessable password or one that can be cracked in a short period of time using an automated program. I should take this opportunity to point out that while this article will help protect against a brute force attack, it will not eliminate it. All passwords are crackable. What makes them crackable is time, and what separates the good passwords from bad is the time it would take to crack it. This article will not cover good encryption. No matter how good a password is, if someone is watching the flow of network traffic, they could capture and record your password if the communication is not protected with encryption.

This is a separate topic which may be covered in a future article. This article is three-fold. First, to give you an understanding of the need for good passwords. Second, if you develop or administer a password enabled site, I will explain how to add a few lines of PHP code to your site to force strong passwords. Lastly, I will share a common technique that will help remembering better passwords easier. Lets take a moment to analyze a couple different password techniques.

Passwords can be categorized using three conditions:

  1. Length
  2. Complexity
  3. Diversity of characters It takes a combination of these conditions to make for really decent passwords.

The first one is easy: Length. A password of four or less characters would be considered a very weak password. The time it could take to crack a short password versus a longer one is dramatically less. Examples of short, weak passwords: * "hi" * "dog" * "f9" * "1234"

The next condition is complexity. Many people use names, places, and other normal words as passwords. This is a common practice because these are easier to remember. What can you remember longer, Your mother's name, or ws3LL498uWBSdf8? Right, I know the answer to that already. The problem with this, is that there is a common technique to break that kind of password. This is commonly known as the 'dictionary' or 'word based' attack. A malicious person would have a database of all the common words found in a dictionary along with common names and places. This would make a brute force attack much more successful for an automated program because to a computer the list of dictionary type words are relatively short. Some people think they are clever by adding a number to the password, however brute force programs check for those too. Examples of dictionary based, weak passwords: * "barbra99" * "century" * "Washington" * "acme001" * "Dragon4"

Finally we add diversity. Here is a quick puzzle for you. Try to guess an eight-letter word using the letters a, b, and c. How long would it take and how many tries would it take to guess aabbbbcc? This isn't a very fun puzzle and if you were bored enough or driving from California to Florida you may give it a try. Now, try to guess an eight-letter word using different combinations of the letters a through z (upper and lower case), 1 through 9, and all of the symbols above the numbers on your keyboard? How long would it take you to guess B&f@0sP4? I would guess a lot longer.

This is NOT one of my passwords, by the way.

It would also take a computer much longer to guess it as well, which is why it is always a good idea to have diversity in you passwords. It makes them much more difficult (time) to crack. Applying this technique to your PHP Application Now that you have a good understanding of what good passwords are and why you need them, Lets look at how you can enforce these in your PHP web application. For this how-to I am using a standard Debian Linux system with apache and php. You can certainly adjust this for your distribution or UNIX variant, But I can't cover all of them in the scope of this article Search Google for the answer.

Most Linux distributions come equipped with a utility called cracklib. Cracklib is a handy tool that the Linux passwd utility uses to enforce good passwords. Unfortunately PHP does not come packaged with the ability to use cracklib out of the box. For this we are going to have to recompile PHP. Debian is, in my opinion, vastly superior with it's package management and I would like to keep the software installed on my system that way for ease of management. I dont like to venture too far off course with source tarballs that I have to manually install and keep track of. That being said I am going to use the debian source package from the apt repository to pull down the source, so I can easily build a debian package.

$ sudo apt-get source php5

This will pull down the php5 source code, which is already tailored for the debian system, and modify it. Once the source is downloaded, cd into the 'debian' folder within the php directory. The file to look for is called 'rules'. Look for a line that stars with 'COMMON_CONFIG='. You will notice that there are many options that are used to compile php4. We are going to add '--with-crack=/usr' to those options. You can fit it in between any of the other options, but be sure to add a backslash () so it continues the line just like the rest of them unless it is the last option.

Mine looks like this:

COMMON_CONFIG= --build=$(PHP4_BUILD_GNU_TYPE)-gnu --host=$(PHP4_HOST_GNU_TYPE)-gnu --mandir=/usr/share/man --enable-memory-limit --disable-debug --with-regex=php --disable-rpath --disable-static --with-pic --with-layout=GNU --with-pear=/usr/share/php --enable-calendar --enable-sysvsem --enable-sysvshm --enable-sysvmsg --enable-track-vars --enable-trans-sid --enable-bcmath --with-bz2 --with-crack=/usr <-- This is the new entry --enable-ctype --with-db4 --without-gdbm --with-iconv --enable-exif --enable-filepro --enable-ftp --with-gettext --enable-mbstring --with-pcre-regex=/usr --enable-shmop --enable-sockets --enable-wddx --disable-xml --with-expat-dir=/usr --with-xmlrpc --enable-yp --with-zlib --with-kerberos=/usr --with-openssl=/usr --with-zip=/usr --enable-dbx --with-mime-magic=$(MAGIC_MIME) --with-exec-dir=/usr/lib/php4/libexec


Once that is done we need to compile it. To build the debian package, cd up one directory to the parent php4-x.x.x directory and run the build command:

$ sudo dpkg-buildpackage -rfakeroot -b

If this throws 'not found' errors, make sure you have the dpkg-dev and fakeroot packages installed. It may complain about missing dependencies (lots of -dev packages) so you can 'apt-get install' those too. If you've successfully built the packages, you can then upgrade your existing php packages with these new ones, which should now be one directory up alongside the top of the php4 directory.

Did I loose anyone yet?

If you've been following along, just 'cd ..' and you should see them in the directory listing. to install them, just like any other debian package, just use dpkg:

$ dpkg -i If you have other php5 packs installed, you may upgrade them as well from your new ones. Otherwise you probably only need the php5_x.x.x... package. Once the pack is installed you will need to restart your web server, if the installation process didn't already do it. To test it out create yourself a test php file with the following contents: phpinfo(); ?> Load this up in your apache and hit it with your browser. You should see all the details of your php install. search for the work 'crack'. You should see a line that reads, "crack support enabled". If so, you are well on your way. Cracklib did not seem to come with a set of dictionary words, which may have been a bug in the debian package. I have a collection of words located HERE for download. uncompress the words file and place it into /usr/share/dict/. once the file is there you can generate CrackLib dictionary from downloaded word list:

$ sudo update-cracklib /var/cache/cracklib/cracklib_dict

Next is to modify your php application. If you know where the password management section of your application is, you should be able to add the following function to it:

function crackit() {

   if (isset($_POST['passwd1'], $_POST['passwd2']) && is_string($_POST['passwd1'])) {
      $temppass = $_POST['passwd1'];
      $dictionary = crack_opendict('/usr/share/cracklib/pw_dict') or die('Unable to open CrackLib dictionary');
      $check = crack_check($dictionary, "$temppass");
      $diag = crack_getlastmessage();
      if ($diag != "strong password") {
         $rpasswd_error_msg = "Password error: $diag";
      else if ($_POST['passwd1'] !== $_POST['passwd2']) {
         $rpasswd_error_msg = 'Passwords do not match'; }
      else if (strlen($_POST['passwd1']) < 6 ) {
         $rpasswd_error_msg = 'Password must be at least 6 characters long'; }
      else {    
         echo "Good Password!n"; exit(0); //exit('window.close();');
      $rpasswd_error = ''.$rpasswd_error_msg.'';
   else {
      $rpasswd_error = '';

Assuming your password variables are passwd1 ( and passwd2 if you enter it twice for verification), this function will first check to make sure it isn't an easy common word (remember the dictionary based words). Next it will check the length to make sure it is long enough. You can call this function somewhere in you password verification code by calling crackit(). You probably will have to modify this code you fit your application. I am just trying to give you a baseline to start from. I have a password checker application, based on this howto. You can try it out at Remembering good passwords Now that I have educated you on the importance of good passwords, Let me try and give you an easy way to remember them. Having a good password is ideal, but if you have to resort to writing them all on a sticky-note and pasting them on your monitor, you may as well just have a t-shirt with your passwords printed on them. Many time have I walked by offices and banks and have seen passwords on post-it notes stuck to monitors. @page { size: 8.5in 11in; margin: 0.79in } P { margin-bottom: 0.08in } --> What I like to do is come up with a phrase. Something that is catchy. I use numbers and symbols and a combination of lower and capital letters. For example, the @ sign is pronounced, 'at'. So I may come up with a phrase that uses the word 'at'. Numbers pronounce like words too, like 8, or 'ate'. and 4, or 'for'. You get the idea. So lets take the phrase, "Lunch at eight, and don't be late.", could be written as Lunch@8&dontBL8. That's an easy phrase to remember. It's nice and long and uses many different characters so the chances are that cracking or guessing this password would take longer than anyone would care to try. Give it try and you'll see that it isn't as hard to remember as you think it would be. Enjoy.