Let’s face it, humans are not well adapted to memorizing strings of random characters; and hence, the average computer user is not very good at creating secure passwords. Most users create passwords made up of easy-to-remember words, like the name of a favorite sports team or maybe the name of a significant other. In this article I will show you how you can make Django require better passwords from your users.
Here are the packages you will need:
Installing the required packages
Step 1: Install CrackLib.
CrackLib is a library for checking that passwords are not easily crackable, or in other words, it makes sure that a password is not based on a simple character pattern or on a dictionary word. CrackLib is a common package that you should be able to find in your distribution’s package manager (or, quite possibly, it could already be installed). Alternatively, you could download the source and follow the installation instructions in the README file. By default, CrackLib installs a python package named cracklib, but it does not have as many features as python-crack. (Redhat does not include the cracklib python package in its cracklib package.)
Step 2 (optional, but recommended): Install extra word dictionaries.
Packaged with CrackLib is a file name cracklib-small. (Some distributions, like RedHat, don’t include this file in their cracklib package, in which case keep reading…) This file is a dictionary of words, simply a long list of words with one word per line. These 50,000 words are a good start, but we can do better. On the CrackLib download page, there is also a package named cracklib-words. After downloading and extracting the package, you will have a single file containing 1,648,379 “words”. Many distributions also have a cracklib-dicts or cracklib-words package that maybe the same or similar to the cracklib-words file on the CrackLib website.
For even more dictionaries, take a look at these word lists. It might also be a good idea to create your own list of words. For example, if you work for a company in the financial industry, it would be a good idea to make a list of words and slang specific to that industry. If you will be dealing with non-english speaking users, it would be a good idea to find some dictionaries in other languages.
Step 3: Create the word indexes that get used by CrackLib.
Now that we have our dictionaries, we need to compile them into an index that CrackLib uses. So, put all your dictionaries in one directory (/usr/share/dict/ is a common place). Depending on your distribution, there will be different commands to run. On gentoo (or if you installed from source), the following (as root) should do the trick:
create-cracklib-dict /usr/share/dict/*
And on RedHat:
mkdict /usr/share/dict/* | packer /usr/lib/cracklib_dict
These commands should create the following files:
/usr/lib/cracklib_dict.hwm
/usr/lib/cracklib_dict.pwd
/usr/lib/cracklib_dict.pwi
Step 4: Install python-crack
If your distribution’s package manager doesn’t include python-crack, then you will have to download and install it yourself. Neither Gentoo nor RedHat include this package, so I will walk you through the install. Download and unpack python-crack. Now, cd into the directory and run
./configure
By default, configure will setup python-crack’s files to be installed to /usr/local. This means that you will have to add /usr/local/lib/python2.4/site-packages to your PYTHONPATH. Alternatively, you could add a --prefix=/usr to the end of the configure command to install python-crack’s files to the usual /usr/lib/python2.4/site-packages directory.
If you get this error:
checking for prefix of the default cracklib dictionary database… unknown
configure: error: crack.h does not define CRACKLIB_DICTPATH. Please use DEFAULT_DICTPATH, see ./configure –help
then set the DEFAULT_DICTPATH variable when running configure, like so
./configure DEFAULT_DICTPATH=/usr/lib/cracklib_dict
Now run
make
make install
Now that we are finished installing, lets test out python-crack
$ python
Python 2.4.3 (#1, Jun 28 2006, 23:41:37)
[GCC 3.4.6 (Gentoo 3.4.6-r1, ssp-3.4.5-1.0, pie-8.7.9)] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import crack
>>> crack.VeryFascistCheck(‘foo’)
[snip]
ValueError: it is WAY too short
>>> crack.VeryFascistCheck(‘foobar’)
[snip]
ValueError: it is based on a dictionary word
>>> crack.VeryFascistCheck(‘3#hsad2U>u2u’)
‘3#hsad2U>u2u’
VeryFascistCheck() raises a value error and prints an explaination if the password is not strong enough, otherwise it echos back the password.
Creating the Django Manipulator
from django import forms
class NewUserForm(forms.Manipulator):
def __init__(self):
self.fields = [
forms.TextField(field_name="username", length=20, maxlength=20, is_required=True),
forms.PasswordField(field_name="password", length=20, maxlength=50, is_required=True,
validator_list=[isStrongPassword]),
forms.PasswordField(field_name="confirm_password", length=20, maxlength=50, is_required=True,
validator_list=[forms.validators.RequiredIfOtherFieldGiven("password", "You must confirm password"),
forms.validators.AlwaysMatchesOtherField("password", "Passwords did not match"),]),
]
def isStrongPassword(field_data, all_data):
"""Test the password with cracklib to make sure it is strong."""
import crack
# Increase the number of credits required from the default of 8 if you want.
#crack.min_length = 11
try:
crack.VeryFascistCheck(field_data)
except ValueError, message:
raise forms.validators.ValidationError, "Password %s." % str(message)[3:]
Notice that I added isStrongPassword to the password field’s validator_list. Now you are ready to put the NewUserForm manipulator to use in your you views.py. After running the manipulator’s get_validation_errors(), bad passwords will generate errors like “Password is based on a dictionary word” or “Password does not contain enough DIFFERENT characters.” For help on using manipulators in your view, see the Forms, fields, and manipulators documentation.
If you want to make Django’s built-in authentication require stronger passwords, then you could add validator_list=[isStrongPassword] to the password field of django.contrib.auth.models.User.
Now, go forth and require strong passwords.
Contraseñas fuertes en Django
Artículo en inglés en el que muestran la forma de implementar un sistema de contraseñas seguras en Django, usando la biblioteca CrackLib y python-crack. Django está a punto de sacar su versión 1.0 http://www.eweek.com/article2/0,1759,2013791,00.asp
Trackback by meneame.net — September 11, 2006 @ 12:35 pm
Thanks for the very useful post! It helped me getting python-crack installed on Solaris 10, and we have a very functional strong password enforcing change form using Django.
Comment by Chris I — October 11, 2006 @ 10:49 am
[...] you are using Django and want more info: http://gdub.wordpress.com/2006/08/26/using-cracklib-to-require-stronger-passwords/ No Comments Leave a Commenttrackback addressThere was an error with your comment, please try [...]
Pingback by Configuring cracklib python-crack and a better system cracklib_dict in Red Hat Fedora Core 9 « Kevin Andle’s Technosphere — August 20, 2008 @ 1:04 am
[...] If you are using Django and want more info: http://gdub.wordpress.com/2006/08/26/using-cracklib-to-require-stronger-passwords/ [...]
Pingback by Configuring Cracklib, Upgrading cracklib_dict and Building python-crack « Red Hat Fedora Core 9 — September 1, 2008 @ 10:42 pm
[...] was doing some Google and found a very nice cracklib2 bindings for Python. It should cut down the time to write the code [...]
Pingback by Ishwor’s munge, some drivels.. » Blog Archive » Checking for strong password — November 23, 2008 @ 5:05 am