What is the best way to check the strength of a password?
What is the best way of ensuring that a user supplied password is a strong password in a registration or change password form?
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
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.
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;
}