views:

2276

answers:

16

See also How do you compute password complexity?

What is the best way of ensuring that a user supplied password is a strong password in a registration or change password form?

EDIT: one idea I had (in python)

def validate_password(passwd):
    conditions_met = 0
    conditions_total = 3
    if len(passwd) >= 6: 
        if passwd.lower() != passwd: conditions_met += 1
        if len([x for x in passwd if x.isdigit()]) > 0: conditions_met += 1
        if len([x for x in passwd if not x.isalnum()]) > 0: conditions_met += 1
    result = False
    print conditions_met
    if conditions_met >= 2: result = True
    return result
A: 

I like using Microsoft's password checker

Bob
A: 

If you have the time, run a password cracker against it.

Daniel Papasian
A: 

I've always like the Google password strength api.

you can find some information here

http://www.codeproject.com/KB/ajax/GooglePasswordStrength.aspx

Erratic
Summarised from that article, just do a HTTP request to:https://www.google.com/accounts/RatePassword?Passwd=<password>And it returns a score from 1..4 for how secure the password is.
Peter Boughton
That's good and all, but I don't think I want to be sending passwords around like that, even if it is a secure connection.
dawnerd
A: 

There's the open and free John the Ripper password cracker which is a great way to check an existing password database.

tante
A: 

Password strength checkers, and if you have time+resources (its justified only if you are checking for more than a few passwords) use Rainbow Tables.

Mostlyharmless
A: 

With a series of checks to ensure it meets minimum criteria:

  • at least 8 characters long
  • contains at least one non-alphanumeric symbol
  • does not match or contain username/email/etc.
  • etc

Here's a jQuery plugin that reports password strength (not tried it myself): http://phiras.wordpress.com/2007/04/08/password-strength-meter-a-jquery-plugin/

And the same thing ported to PHP: http://www.alixaxel.com/wordpress/2007/06/09/php-password-strength-algorithm/

Peter Boughton
+8  A: 

Depending on the language, I usually use regular expressions to check if it has:

  • At least one uppercase and one lowercase letter
  • At least one number
  • At least one special character
  • A length of at least six characters

You can require all of the above, or use a strength meter type of script. For my strength meter, if the password has the right length, it is evaluated as follows:

  • One condition met: weak password
  • Two conditions met: medium password
  • All conditions met: strong password

You can adjust the above to meet your needs.

VirtuosiMedia
A: 

Alec Muffett's CrackLib is good for this.

Paul Reiners
+1  A: 

The two simplest metrics to check for are:

  1. Length. I'd say 8 characters as a minimum.
  2. Number of different character classes the password contains. These are usually, lowercase letters, uppercase letters, numbers and punctuation and other symbols. A strong password will contain characters from at least three of these classes; if you force a number or other non-alphabetic character you significantly reduce the effectiveness of dictionary attacks.
Dave Webb
+1  A: 

A general algorithm is outlined in the wikipedia page at http://en.wikipedia.org/wiki/Random_password_generator#Stronger_methods . I also found a couple of scripts here - http://webtecker.com/2008/03/26/collection-of-password-strength-scripts/. Some of those are under the MIT License, so you can look at the code and figure out how they calculate the strength. I found the wikipedia entry helpful too.

A: 

In addition to the standard approach of mixing alpha,numeric and symbols, I noticed when I registered with MyOpenId last week, the password checker tells you if your password is based on a dictionary word, even if you add numbers or replace alphas with similar numbers (using zero instead of 'o', '1' instead of 'i', etc.).

I was quite impressed.

Steve Morgan
+4  A: 

The object-oriented approach would be a set of rules. Assign a weight to each rule and iterate through them. In psuedo-code:

abstract class Rule {

    float weight;

    float calculateScore( string password );

}

Calculating the total score:

float getPasswordStrength( string password ) {     

    float totalWeight = 0.0f;
    float totalScore  = 0.0f;

    foreach ( rule in rules ) {

       totalWeight += weight;
       totalScore  += rule.calculateScore( password ) * rule.weight;

    }

    return (totalScore / totalWeight) / rules.count;

}

An example rule algorithm, based on number of character classes present:

float calculateScore( string password ) {

    float score = 0.0f;

    // NUMBER_CLASS is a constant char array { '0', '1', '2', ... }
    if ( password.contains( NUMBER_CLASS ) )
        score += 1.0f;

    if ( password.contains( UPPERCASE_CLASS ) )
        score += 1.0f;

    if ( password.contains( LOWERCASE_CLASS ) )
        score += 1.0f;

    // Sub rule as private method
    if ( containsPunctuation( password ) )
        score += 1.0f;

    return score / 4.0f;

}
+1 for the weight idea
Gabe Moothart
I wonder if it would make more sense to implement this in a more functional manner. Having to subclass a whole bunch of rules that are probably going to be used once seems like a lot of wasted typing. For instance create a Rule class and assign an anonymous function to its rule property for a given instance.
SapphireSun
I'm not using Java so this may or may not work in that language.
SapphireSun
I've recently implemented a password strength checker based on this suggestion. The flexibility of being able to add and tweak rules and weights allows for some swift iteration. After spending some time deriving decent rules, by comparing known good and bad passwords, I found an approach that can recognise dictionary words and proper nouns without a dictionary.
Jon Cram
A: 

Hi, I wrote a small Javascript application. Take a look: Yet Another Password Meter. You can download the source and use/modify it under GPL. Have fun!

ReneS
A: 

If they don't get it wrong at least once a week, while trying to log in then its too weak.

paperhorse
I didn’t know whether to downvote this for being a bad answer or to upvote it for being a funny one, so I’m leaving a comment instead.
Aristotle Pagaltzis
A: 

I don't know if anyone will find this useful, but I really liked the idea of a ruleset as suggested by phear so I went and wrote a rule Python 2.6 class (although it's probably compatible with 2.5):

import re

class SecurityException(Exception):
    pass

class Rule:
    """Creates a rule to evaluate against a string.
    Rules can be regex patterns or a boolean returning function.
    Whether a rule is inclusive or exclusive is decided by the sign
    of the weight. Positive weights are inclusive, negative weights are
    exclusive. 


    Call score() to return either 0 or the weight if the rule 
    is fufilled. 

    Raises a SecurityException if a required rule is violated.
    """

    def __init__(self,rule,weight=1,required=False,name=u"The Unnamed Rule"):
     try:
      getattr(rule,"__call__")
     except AttributeError:
      self.rule = re.compile(rule) # If a regex, compile
     else:
      self.rule = rule  # Otherwise it's a function and it should be scored using it

     if weight == 0:
      return ValueError(u"Weights can not be 0")

     self.weight = weight
     self.required = required
     self.name = name

    def exclusive(self):
     return self.weight < 0
    def inclusive(self):
     return self.weight >= 0
    exclusive = property(exclusive)
    inclusive = property(inclusive)

    def _score_regex(self,password):
     match = self.rule.search(password)
     if match is None:
      if self.exclusive: # didn't match an exclusive rule
       return self.weight
      elif self.inclusive and self.required: # didn't match on a required inclusive rule
       raise SecurityException(u"Violation of Rule: %s by input \"%s\"" % (self.name.title(), password))
      elif self.inclusive and not self.required:
       return 0
     else:
      if self.inclusive:
       return self.weight
      elif self.exclusive and self.required:
       raise SecurityException(u"Violation of Rule: %s by input \"%s\"" % (self.name,password))
      elif self.exclusive and not self.required:
       return 0

     return 0

    def score(self,password):
     try:
      getattr(self.rule,"__call__")
     except AttributeError:
      return self._score_regex(password)
     else:
      return self.rule(password) * self.weight

    def __unicode__(self):
     return u"%s (%i)" % (self.name.title(), self.weight)

    def __str__(self):
     return self.__unicode__()

I hope someone finds this useful!

Example Usage:

rules = [ Rule("^foobar",weight=20,required=True,name=u"The Fubared Rule"), ]
try:
    score = 0
    for rule in rules:
        score += rule.score()
except SecurityException e:
    print e 
else:
    print score

DISCLAIMER: Not unit tested

SapphireSun
If someone knows a better place for putting code samples and such and/or SO is inappropriate, let me know.
SapphireSun