Password strength analyzer with PHP

Posted 1 year ago     1191      php password

Many times happens to have to determinate how much a password is strong and usually for do that we simply measure the length. For increase the password security I've created this function which measure also some others factors:
Length of the given password;
If password has at least 1 lowercase letter, 1 uppercase letter and 1 number;
How many times a letter repeats itself;
If are present words given by array, like person's name, birthdate...
If the password is in a given password dictionary file.
The last condition is meant not as a linguistic words dictionary but a wordlist with common passwords used for hash brute force hacking, for example rockyou.txt, this file can be downloaded and contains about 14 milion of common use passwords.
Here's the link for download rockyou.txt or other wordlists: Passwords.
Note that compressed format like GZip are not yet supported (I've to improve search speed), also SQLite is not yet suported (it's very fast but has also huge dimension), if you want to use another custom file you might write passwords in a simple txt file and separe them by a breakline (\n)


function checkPasswordStrength($password, $grade = 3, $info = NULL, $file = NULL, $ci = true){ if ( empty($password) ){ return false; } $grade = intval($grade); if ( $grade < 1 ){ return false; } $info = empty($info) ? NULL : $info; $file = empty($file) ? NULL : $file; $score = 0; $length = mb_strlen($password, 'UTF-8'); $score = $length < 15 ? - ( floor( ( ( 15 - $length ) * 100 ) / 15 ) ) : 0; if ( $grade >= 2 ){ $buffer = mb_strtolower($password, 'UTF-8'); $score += $buffer != $password ? 0 : -10; $score += mb_strtoupper($password, 'UTF-8') != $password ? 0 : -10; $score += preg_match('/[0-9]/', $password) ? 0 : -10; $buffer = $ci == true ? $buffer : $password; if ( $grade >= 3 ){ $chars = array(); for( $i = 0 ; $i < $length ; $i++ ) { $char = mb_substr($password, $i, 1, 'UTF-8'); $chars[$char] = array_key_exists($char, $chars) ? $chars[$char] + 1 : 0; } foreach ( $chars as $key => $value ){ if ( $value > 1 ){ $score += -$value; } } if ( $grade >= 4 ){ if ( $info != NULL ){ if ( $ci == true ){ foreach ( $info as $key => $value ){ if ( mb_strpos($buffer, mb_strtolower($value, 'UTF-8'), NULL, 'UTF-8') !== false ){ $score += -5; } } }else{ foreach ( $info as $key => $value ){ if ( mb_strpos($buffer, $value, NULL, 'UTF-8') !== false ){ $score += -5; } } } } if ( $grade >= 5 ){ if ( $file != NULL && file_exists($file) && !is_dir($file) ){ $search = $buffer . "\n"; $handle = fopen($file, 'r'); $last_buffer = ''; $chunk_size = $length < 4096 ? 4096 : $length; while ( !feof($handle) ) { $chunk = fread($handle, $chunk_size); $buffer = $last_buffer . $chunk; if ( strpos($buffer, $search) !== false ) { $score += -10; break; } $last_buffer = $chunk; } } } } } } $buffer = 100 + $score; $buffer = $buffer > 100 ? 100 : $buffer; $buffer = $buffer < 0 ? 0 : $buffer; return $buffer; }

Parameters:

$password: The password which will be checked
$grade: Checks to do, according to overwritten feature list
$info: User's informations array
$file: Passwords' dictionary location
$ci: If user's informations compares and dictionary analysis must be done in case-insensitive way

The function will return estimated password security score in percentage (integer).

Usage example:


//Simple: (will return 34%) echo checkPasswordStrength('password', 3) . '%'; //With personal informations: (will return 45%) echo checkPasswordStrength('123enrico', 4, array('Enrico', 'RyanJ93')) . '%'; //Complete: (will return 5%) echo checkPasswordStrength('enrico', 5, array('Enrico', 'RyanJ93'), '/rockyou.txt') . '%'; //Complete with better password: (will return 74%) echo checkPasswordStrength('aBetterP4ss', 5, array('Enrico', 'RyanJ93'), '/rockyou.txt') . '%';

TO DO:

1) Adding support for GZip files and SQLite;
2) Add combinatorial dictionary check.

Tested on Ubuntu 14.04 and OSX 10.11
Speed test average (based on previus examples):

1) 0.0003 seconds;
2) 0.00032 seconds;
3) 0.0006 seconds;
4) 0.382 seconds.

Comments

There are no comments yet.

You need to be logged in to post comments.



Welcome to Snippet Repo!

Discover, share and save useful code snippets.

Join our community over over 2,000 members! Currently a 48% acceptance rate. Apply for membership →