Calculating password strength

A lot of websites display the strength of the password chosen by the user on their registration forms. The goal of this practice is to help the user choose a better, stronger password which cannot be guessed or brute-forced easily.

In this recipe, we're going to make a password strength calculator. It will determine the password strength by calculating the number of brute-force attempts that a potential attacker must make before guessing the password. It will also warn the user if his password is in a list of 500 commonly used passwords.

Getting ready

Before we begin, its important to look at how we're going to calculate the number of brute-force attempts that an attacker must make. We're going to take a look at two factors: the length of the password and the size of the character set used by the user.

The size of the character set can be determined as follows:

  • If the user adds a lowercase alphabet letter in his password, the size of the character set grows by 26 (the number of letters in the alphabet)
  • Additional 26 are added if the user uses an uppercase letter anywhere except at the beginning of the password
  • 10 characters are added if the user adds a number
  • 24 characters are added if the user adds a special character such as dot, comma, braces, ampersand, and so on
  • 20 characters are added if the user uses a unicode character not found in other tables

How to do it...

Let's write the HTML and JavaScript code:

  1. Create a simple HTML page with a password input, then add a div element, which we will update with the password strength result. Common passwords will be included via a script named common-passwords.js:
    <!DOCTYPE HTML>
    <html>
        <head>
            <title>Password strength calculator</title>
       </head>
       <body>
       <input type="password" id="pass" value="" />
       <div id="strength">0 (very poor)</div>
       <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
       <script type="text/javascript" src="common-passwords.js"></script>
       <script type="text/javascript" src="example.js"></script>
       </body>
    </html>

    The common-passwords.js script is not included here, but can be found in the supplementary code.

  2. The code checking the logic is in example.js:
    $(function() {
        function isCommon(pass) {
          return ~window.commonPasswords.indexOf(pass);
        }
    
        function bruteMagnitude(pass) {
          var sets = [
          { regex: /d/g, size: 10 },
          { regex: /[a-z]/g, size: 26 },
          { regex: /[A-Z]/g, size: 26 },
          { regex: /[!-/:-?[-`{-}]/g, size: 24 },
          ];
          var passlen = pass.length,
          szSet = 0;
    
          sets.forEach(function(set) {
            if (set.regex.test(pass)) {
              szSet += set.size;
              pass = pass.replace(set.regex, ''),
            }
            });
            // other (unicode) characters
            if (pass.length) szSet += 20;
            return passlen * Math.log(szSet) / Math.LN10;
        }
    
        var strengths = ['very poor', 'poor', 'passing', 'fair',
            'good', 'very good', 'excellent'];
    
        function strength(pass) {
            if (isCommon(pass) || !pass.length) return 0;
            var str = bruteMagnitude(pass);
            return str < 7  ? 0 // very poor
                 : str < 9  ? 1 // poor      - 10 million - 1 billion
                 : str < 11 ? 2 // passing   - 1 billion - 100 billion
                 : str < 13 ? 3 // fair      - 100 billion - 10 trillion
                 : str < 15 ? 4 // good      - 10 trillion - 1 quadrillion
                 : str < 17 ? 5 // very good - 1-100 quadrillion
                 : 6;           // excellent - over 100 quadrillion
        }
  3. Update the div element indicating password strength when a key is pressed in the password field:
        $('#pass').on('keyup keypress', function() {
          var pstrength = strength($(this).val());
          $("#strength").text(pstrength + ' (' + strengths[pstrength] + ')'),
        });
    });

How it works...

The calculation is split into two parts: checking for password commonality and password complexity.

We check if the password is common simply by checking if it can be found in the commonPasswords array provided by common-password.js. Array#indexOf returns 1 if the entry was not found. The bitwise not operator ~ turns that value into zero, which evaluates to false. All the other numbers greater than or equal to 0 will have negative values, which are true values. Thus, the entire expression returns true if the password is found in the array.

In the bruteMagnitude function we calculate the password's brute-force order of magnitude using the passwordLength and character setsize methods:

magnitude = log10(setSize passwordLength) = passwordLength * log10(setSize)

This is an approximate order of magnitude of the number of passwords that a brute-force password attacker must try to guess the password.

Based on this information, we can now give an actual password strength. If the password is among the top 500 common passwords, it will be classified as poor. Otherwise it will be classified according to its brute force magnitude using the following table:

Magnitude

Number of passwords

Rating

Less than 7

Less than 10 million

Very poor

7 to 8

10 million to 1 billion

Poor

9 to 10

1 billion to 100 billion

Passing

11 to 12

100 billion to 10 trillion

Fair

13 to 14

10 trillion to 1 quadrillion

Good

15 to 17

1 to 100 quadrillion

Very good

Greater than 17

Greater 100 quadrillion

Excellent

The classification, along with the descriptive text will be updated on every key press and displayed to the user below the password field.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.194.123