Verifying password strength using JavaScript I have a function which verifies the "Password" field and suggests the user to enter a strong password.  I also have a label named "Password Strength", referring to the strength of a password (very weak, weak, medium, etc).

I'm just wondering if there is a better way to re-write this code.



function chkPasswordStrength(txtpass,strenghtMsg,errorMsg)
   {
     var desc = new Array();
     desc[0] = "Very Weak";
     desc[1] = "Weak";
     desc[2] = "Better";
     desc[3] = "Medium";
     desc[4] = "Strong";
     desc[5] = "Strongest";
   
     errorMsg.innerHTML = ''
     var score   = 0;

     //if txtpass bigger than 6 give 1 point
     if (txtpass.length &gt; 6) score++;

     //if txtpass has both lower and uppercase characters give 1 point
     if ( ( txtpass.match(/[a-z]/) ) &amp;&amp; ( txtpass.match(/[A-Z]/) ) ) score++;

     //if txtpass has at least one number give 1 point
     if (txtpass.match(/\d+/)) score++;

     //if txtpass has at least one special caracther give 1 point
     if ( txtpass.match(/.[!,@,#,$,%,^,&amp;,*,?,_,~,-,(,)]/) ) score++;

     //if txtpass bigger than 12 give another 1 point
     if (txtpass.length &gt; 12) score++;

     strenghtMsg.innerHTML = desc[score];
     strenghtMsg.className = "strength" + score;
  
  if (txtpass.length &lt; 6)
  {
  errorMsg.innerHTML = "Password Should be Minimum 6 Characters"
  errorMsg.className = "errorclass"
  }
  
  
   }
&lt;style type="text/css"&gt;
             .strength0
            {
                width:200px;
                background:#B20E37;
                text-align: center;
                font-weight: bold;
            }
 
            .strength1
            {
                width:200px;
                background:#D32847;
                text-align: center;
                font-weight: bold;
            }
 
            .strength2
            {
                width:200px;
                background:#ff5f5f;
                text-align: center;
                font-weight: bold;
            }
 
            .strength3
            {
                width:200px;
                background:#83D680;
                 text-align: center;
                font-weight: bold;
            }
 
            .strength4
            {
                background:#4dcd00;
                width:200px;
                 text-align: center;
                font-weight: bold;
            }
 
            .strength5
            {
                background:#399800;
                width:200px;
                text-align: center;
                font-weight: bold;
            }
   
    .errorclass
    {
     font-weight:bold;
     font-size: 10px;
         color: #4F080B;
        font-family: Arial, 
    }
&lt;/style&gt;
&lt;tr&gt;
&lt;%= label "Password",:mandatory=&gt;true %&gt;
&lt;td&gt;

&lt;input id="user_password" type="password" size="30" name="user[password]"  onkeyup="chkPasswordStrength(this.value,document.getElementById('strendth'),document.getElementById('error'))"&gt;
                 
&lt;/td&gt;

&lt;td id="strendth" class="strength5"&gt;&lt;b&gt;Password Strength&lt;/td&gt;
 
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;
Dislcaimer: I'm not a security researcher and the following answer is compiled from my own, humble knowledge. The math is very basic and there are many things to consider, if in doubt, pay Security a visit. Also there are many factors that can kill password security completely, for example the user themselves or social engineering.


In this case I'm not reviewing the code, but I'm reviewing your program logic.

A short talk about password security

Let's first define the rules you use (the term "special chars" here for further on refers to the set !@#$%^&amp;*?_~-()):


Password length > 6: 1 Point
Password length > 12: 1 Point
Password contains at least one lower and one upper case letter: 1 Point
Password contains at least one digit: 1 Point
Password contains at least one of the special chars: 1 Point


Your scale goes from 0 (Very Weak) to 5 (Strongest). That means a password based on length can never go beyond 2 (Better), but a short password can be 4 (Strong). This is bad if we keep in mind that strong passwords do not necessarily use a broad character set.

The following passwords are considered Strong by your algorithm:


abcdE$1
qwert!1
1111Aa@


Now these do not look like strong ones to me, let's have a look at how many possible combinations such a password has. The total character set for these passwords is 26 (lower) + 26 (upper) + 10 (digits) + 14 (special) = 76.


  76^7 = ~1.4 * 10^13 = ~14 trillion


So an attacker which knows the character set and the length of the password, has to search roughly 14 trillion combinations until they find the password. Though, that is the worst case scenario, could be that they find it on the third try, but could be that it is the next to the last. Todays computers can do more then 500 million guesses per second, that's roughly 8 hours...this can not be considered secure in any way.

Let's have a look at the other side of the spectrum, the following password is only considered Better:


  thisisaverylongpasswordbecause (This is a very long password because)


It only has a character set of 26 and a length of 30 (the maximum for your system if I've seen this correctly).


  26^30 = ~ 2.8 * 10^42 = ~2.8 tredecillion


I have no idea what that number is supposed to mean, so let's compare it. Okay, that doesn't help either...maybe if we put it into a timeframe, 500 million guesses per second again:


  ~1.8 * 10^26 years


That's actually good news! That's well before the heat death of the universe.

So, less nonsense, more talk: What's going on here?

The strength of a password can not reliable be defined. But we know two things:


The longer it is, the more combinations you have to go through.
The more different characters it uses, the more combinations you have to go through.


The difference is that one adds to the base, and the other to the exponent. A higher exponent weighs in heavier than a higher base and yields more total combinations. So whenever possible use a passphrase instead of a password.

Despite being, seemingly, vulnerable to dictionary attacks, the Oxford Dicitonary holds 300 thousand main entries, so if we have a passphrase of 4 words, that's:


  300000^4 = 8.1 * 10^21


And that does not take into account possible misspellings, if the words start uppercase, lowercase or mixed and different languages.

Make the users favor passphrases and long, easier to remember passwords then complicated short ones.

Sell it as a feature!

This will make your marketing department happy, you just implemented support for the more secure passphrases into your software! Let your users know about it by simply adding a short information to the password box:


  We support passphrases up to a length of XX characters!
  
  Passphrases are more secure and easier to remember than ordinary passwords.


And some short information about how to "create" one, and drop any indicator if the password is secure or not.

Who you can and can't help

There are quite many user groups out there, the question is who you want to reach with this help. Let's define three groups:


The "average user", which does not understand why they need to press a button labeled "Delete" to delete something.
The normal user, always ready to learn and looks beyond their own nose.
The technical user, already uses a password manager and/or passphrases.


No matter how hard you try, you will not be able to help the "average user". If you tell them to use a password of minimum length 6, they will use "123456" or "asdfgh". If you tell them to use a password of minimum length 12, they will use "asdfghjkzxcvbn" or "000000000001". They are beyond hope and will actively workaround security measures you implement. Just let 'em be.

The "normal user" on the other hand is ready to learn something new, telling them about passphrases and that you support them will make them want to use passphrases. If your small help text and the rest of the system in that moment is helpful, they will use a passphrase which is not something absolutely stupid.

The "technical user" will be pleased that you support a XX length password and passphrases. They most likely already use a strong and random password and a password manager or passphrases, but that you don't limit them in any way will make them happy.

Secure passwords stored insecure are insecure

It doesn't matter how good the password or passphrase is, if you fail to store in a secure manner, they are insecure.

We will completely leave out social engineering or "harmful" users (there are people after all who have their creditcard PIN on a note in the same wallet), we can't help them.

But what is important that if somebody manages to break into your server and manage to copy the user database, they must not have access to all accounts. This is achieved by simply hashing the passwords with an appropriate method. Even if the attacker now has all the usernames and e-mail addresses, the passwords are still safe.

It will also make the marketing department happy that, despite you've been hacked, they can tell the users that their accounts are still safe (password change advised, obviously).

The great news is, if you hash the passwords there's absolutely no reason to limit password length at all! They will all end up as the same length hash in your database, so you can let me use that sentence from that book as a passphrase.

Ask the right people the right questions

Last but not least, defining what is a strong password depends on many things. If in doubt, pay the people over at Security a visit, that's what they're there for.