Javascript Password Strength Meter

Submitted by geekwisdom on Fri, 2006-01-20 22:49.

What makes a strong password? This quick and dirty password strength meter is meant to help users learn how to create stronger passwords. Because it's written in Javascript the password is never sent over the network. Feel free to audit the code and recommend some better regular expressions, weightings, or bug fixes by submitting a comment.

Tips for strong passwords:

  1. Make your password 8 characters or more
  2. Use mixed case letters (upper and lower case)
  3. Use more than one number
  4. Use special characters (!,@,#,$,%,^,&,*,?,_,~)
  5. Use L33t
  6. Use a random password generator/password vault like Password Safe or pwsafe
  7. Use PasswordMaker



Type the password:

Strength score is:   Strength verdict:


Log:

( categories: Security/Privacy )

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Submitted by mjoinsd on Tue, 2007-09-11 15:32.
Very nice - thanks.


A rather trivial submission but saves CPU cycles.

if(intScore < 16)
{
strVerdict = "very weak"
}
else if (intScore < 25)
{
strVerdict = "weak"
}
else if (intScore < 35)
{
strVerdict = "mediocre"
}
else if (intScore < 45)
{
strVerdict = "strong"
}
else
{
strVerdict = "stronger"
}
Submitted by wazoox on Mon, 2007-09-10 05:05.
because it doesn't detect simple words.
Submitted by ZeBadger on Mon, 2007-09-10 16:39.
I was going look at that, once I was happy with the original code.
Submitted by ZeBadger on Sat, 2007-09-08 13:04.
The weighting in the following code is much better. https://www.doxpop.com/prod/js/passwordStrength.js eg. A full combo means that a bruteforce attack would take a long time. They still have broken regex's though.
Submitted by ZeBadger on Mon, 2007-09-10 03:35.
Erm... I'm talking rubbish. The weighting is the same. Anyone know of any good websites that show bruteforce cracking times for different character usage?
Submitted by ZeBadger on Mon, 2007-09-10 03:42.
This page has some analysis.
http://www.lockdown.co.uk/?pg=combi I'll work out some better weighing from this.
Submitted by ZeBadger on Fri, 2008-01-18 11:17.
<html>

<head>

<script language="JavaScript1.1">

<!-- Begin

/* ************************************************************

Created: 20060120

Author: Steve Moitozo

Description: This is a quick and dirty password quality meter

written in JavaScript so that the password does

not pass over the network

Revision Author: Dick Ervasti (dick dot ervasti at quty dot com)

Revision Description: Exchanged text based prompts for a graphic thermometer

Revision Author: Matt Culverwell (zebadger@hotmail.com)

Revision Description: Fixed regular expressions

Revision Author: Matt Culverwell (zebadger@hotmail.com)

Revision Description: Added brand new weighting based on figures from http://www.lockdown.co.uk/?pg=combi



************************************************************ */

function testPassword(passwd)

{

var description = new Array();

description[0] = "<table><tr><td><table cellpadding=0 cellspacing=2><tr><td height=4 width=30 bgcolor=#ff0000></td><td height=4 width=120 bgcolor=tan></td></tr></table></td><td>   <b>Weakest</b></td></tr></table>";

description[1] = "<table><tr><td><table cellpadding=0 cellspacing=2><tr><td height=4 width=60 bgcolor=#990000></td><td height=4 width=90 bgcolor=tan></td></tr></table></td><td>   <b>Weak</b></td></tr></table>";

description[2] = "<table><tr><td><table cellpadding=0 cellspacing=2><tr><td height=4 width=90 bgcolor=#990099></td><td height=4 width=60 bgcolor=tan></td></tr></table></td><td>   <b>Improving</b></td></tr></table>";

description[3] = "<table><tr><td><table cellpadding=0 cellspacing=2><tr><td height=4 width=120 bgcolor=#000099></td><td height=4 width=30 bgcolor=tan></td></tr></table></td><td>   <b>Strong</b></td></tr></table>";

description[4] = "<table><tr><td><table><tr><td height=4 width=150 bgcolor=#0000ff></td></tr></table></td><td>   <b>Strongest</b></td></tr></table>";

description[5] = "<table><tr><td><table><tr><td height=4 width=150 bgcolor=tan></td></tr></table></td><td>   <b>Begin Typing</b></td></tr></table>";



var base = 0

var combos = 0



if (passwd.match(/[a-z]/))

{

base = (base+26);

}



if (passwd.match(/[A-Z]/))

{

base = (base+26);

}



if (passwd.match(/\d+/))

{

base = (base+10);

}



if (passwd.match(/[>!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/))

{

base = (base+33);

}



combos=Math.pow(base,passwd.length);



if(combos == 1)

{

strVerdict = description[5];

}

else if(combos > 1 && combos < 1000000)

{

strVerdict = description[0];

}

else if (combos >= 1000000 && combos < 1000000000000)

{

strVerdict = description[1];

}

else if (combos >= 1000000000000 && combos < 1000000000000000000)

{

strVerdict = description[2];

}

else if (combos >= 1000000000000000000 && combos < 1000000000000000000000000)

{

strVerdict = description[3];

}

else

{

strVerdict = description[4];

}





document.getElementById("Words").innerHTML= (strVerdict);



}

// End-->

</script>



</head>



<body>

<table><tr valign=top><td><form name="commandForm">

Type password: <input type=password size=30 maxlength=50 name=password onkeyup="testPassword(document.forms.commandForm.password.value);" value="">

<br/><font color="#808080">Minimum 6 Characters</td><td><font size="1">  Password Strength:</font><a id="Words"><table><tr><td><table><tr><td height=4 width=150 bgcolor=tan></td></tr></table></td><td>   <b>Begin Typing</b></td></tr></table></a></td></tr></table>

</td></tr></table>



</form>



<pre>

This works by working out how many sets of characters you have used from

<UL>

<LI>Upper (set of 26)</LI>

<LI>Lower (set of 26)</LI>

<LI>Numeric (set of 10)</LI>

<LI>Symbols (set of 33)</LI>

</UL>

It then works out the number of combinations of passwords that could be made based on the sets that you have used and the password length.





Weakest < 1000000

Weak < 1000000000000

Improving < 1000000000000000000

Strong < 1000000000000000000000000

Strongest >=1000000000000000000000000



</pre>





</body>

</html>
Submitted by ZeBadger on Fri, 2008-01-18 11:29.
I've written the above code that calculates the number of combinations that the sets of characters use and then weights them based on that. Not sure that I've given it good numbers for the weighting.
Submitted by ZeBadger on Fri, 2007-09-07 09:23.
I've made some changes to the regex to make it work (like the last combo) and in some cases just to make it easier. Here is the whole regex section.
// LETTERS
if (passwd.match(/[a-z]/)) // [verified] at least one lower case letter
{
intScore = (intScore+1)
} if (passwd.match(/[A-Z]/)) // [verified] at least one upper case letter
{
intScore = (intScore+5)
} // NUMBERS
if (passwd.match(/\d+/)) // [verified] at least one number
{
intScore = (intScore+5)
} if (passwd.match(/(\d.*\d.*\d)/)) // [verified] at least three numbers
{
intScore = (intScore+5)
} // SPECIAL CHAR
if (passwd.match(/[!,@#$%^&*?_~]/)) // [verified] at least one special character
{
intScore = (intScore+5)
} if (passwd.match(/([!,@#$%^&*?_~].*[!,@#$%^&*?_~])/)) // [verified] at least two special characters
{
intScore = (intScore+5)
} // COMBOS
if (passwd.match(/[a-z]/) && passwd.match(/[A-Z]/)) // [verified] both upper and lower case
{
intScore = (intScore+2)
} if (passwd.match(/\d/) && passwd.match(/\D/)) // [verified] both letters and numbers
{
intScore = (intScore+2)
} // [Verified] Upper Letters, Lower Letters, numbers and special characters
if (passwd.match(/[a-z]/) && passwd.match(/[A-Z]/) && passwd.match(/\d/) && passwd.match(/[!,@#$%^&*?_~]/))
{
intScore = (intScore+2)
}
Submitted by willem.spruijt on Sun, 2007-09-30 12:57.
Hi Guys,
I used this script to create a dynamic version with scriptaculous, click here to see the (nice :-) ) result.
Submitted by adicrst on Wed, 2007-08-15 20:45.
where do i download the javascript ?
Submitted by geekwisdom on Wed, 2007-08-22 14:00.
You can download the script from here.
Submitted by geekwisdom on Tue, 2006-08-01 22:49.
doxpop.com is using a derivative of the password strength meter on their subscription page. They too have replaced the verbose output with a slick bar graph. Nicely done Ryan!
Submitted by geekwisdom on Mon, 2007-04-09 11:39.
Submitted by ryanvm on Mon, 2006-06-19 10:12.
Hi Steve, Your script looks very useful, but I was wondering what license it is distributed under, as it isn't explicitly stated in the source code. Is it BSD? GPL? Public domain? Perhaps I'm just not looking in the right place. Thanks.
Submitted by geekwisdom on Tue, 2006-06-20 12:26.
I just added the MIT License to the source code. So feel free to use it however you like within the terms of the license.
Submitted by jsloey on Fri, 2006-05-19 12:42.
Nice job Steve. I made some minor changes to the regex and used your code to derive a Java version. An example jar file with source and instructions can be found at http://justwild.us/examples/password/ Thanks...
Jim
Submitted by geekwisdom on Tue, 2006-06-20 12:32.
Thanks Jim. Care to send me a patch with regex fixes for my JavaScript?
Submitted by zacksmith on Thu, 2006-11-09 13:46.
hi... thanks for posting this script... it's really great. it's easy to use and modify for any visual feedback desired. i've changed it slightly and now the combo points for letters and numbers seem to be working for me...

if (passwd.match(/([a-zA-Z])/) && passwd.match(/([0-9])/)) { // both letters and numbers

you might have already changed that... or please let me know if that doesn't work. thanks again!
---
zack
zacksmithdesign.com
Submitted by geekwisdom on Sat, 2006-11-11 20:51.
Thanks for the code Zack! I've applied your modification and given you credit.
Submitted by ervasti on Wed, 2006-03-01 19:20.
I have always enjoyed the leading edge developments that Google, Amazon, and Yahoo are always trying to introduce to their user experiences. When Google first introduced their password strength meter, I must admit to a touch a jealousy. I instantly wanted something like that on Quty. While looking at the various server-side offerings out there, I wasn't pleased with any of the solutions. It just seemed like they would have presented us with a very awkward integration project. But, thanks to Steve's core code, I was able to exchange the text based prompt messages with an HTML-based graphics thermometer. In less than 36 hours, my applications lab has tested it and installed it on our Registration page. See it at:
https://secure.quty.com/q,d/Register?cmd=user_country&QDD=global Thanks for a great app Steve! -Dick Ervasti
Cofounder / CTO
Quty Global Auction Network
Submitted by geekwisdom on Wed, 2006-03-01 20:13.
Thanks for the kind words Dick. It's cool that you could find this useful.
Submitted by JayB on Mon, 2007-02-26 14:53.
Found this today and put together a CSS version.
Submitted by geekwisdom on Tue, 2007-02-27 15:45.
I took the liberty of putting it together in a file and putting the MIT license on it so people can feel free to use it. I also merged in a bug fix for one of the regex.