From d2692de44af769b9b712bd2e8292fa71e8d1bc61 Mon Sep 17 00:00:00 2001 From: steinm Date: Tue, 28 Aug 2012 06:25:52 +0000 Subject: [PATCH] - class to calculate the password strength --- inc/inc.ClassPasswordStrength.php | 367 ++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 inc/inc.ClassPasswordStrength.php diff --git a/inc/inc.ClassPasswordStrength.php b/inc/inc.ClassPasswordStrength.php new file mode 100644 index 000000000..1415a2f44 --- /dev/null +++ b/inc/inc.ClassPasswordStrength.php @@ -0,0 +1,367 @@ + * + * All Rights Reserved. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + *************************************************************************/ + +class Password_Strength +{ + private $class_name = "Password Strength"; + private $class_version = "1.0.0"; + private $class_author = "Wolf Software"; + private $class_source = "http://www.wolf-software.com/downloads/php-classes/security-classes/password-strength-class/"; + + private $password = ''; + private $password_info = array(); + private $password_length = 0; + private $score_precision = 2; + + public function class_name() + { + return $this->class_name; + } + + public function class_version() + { + return $this->class_version; + } + + public function class_author() + { + return $this->class_author; + } + + public function class_source() + { + return $this->class_source; + } + + public function __construct() + { + } + + public function simple_calculate() + { + $password = $this->password; + if($this->password_length < 8 || + !preg_match('/[0-9]+/', $password) || + !preg_match('/[a-z]+/', $password) || + !preg_match('/[A-Z]+/', $password) || + !preg_match('/[^0-9a-zA-Z]+/', $password)) + { + $this->password_info['total_score'] = 0; + $this->password_info['rating_score'] = 0; + $this->password_info['rating'] = 'Insufficient'; + } + else + { + $this->password_info['total_score'] = 100; + $this->password_info['rating_score'] = 100; + $this->password_info['rating'] = 'Good'; + } + } + + public function calculate() + { + $this->password_info = array(); + + $this->calculate_length(); + $this->calculate_complexity(); + $this->calculate_charset_complexity(); + $this->calculate_entropy(); + + $this->password_info['password'] = $this->password; + $this->password_info['password_length'] = $this->password_length; + + $total = 0; + $scoreCount = 0; + $keys = array_keys($this->password_info['details']); + foreach ($keys as $key) + { + if (preg_match('/score+$/', $key)) + { + $total += intval($this->password_info['details'][$key]); + $scoreCount ++; + } + } + $rating_score = round($total / $scoreCount, $this->score_precision); + $score_info = $this->get_score_info($rating_score); + + $this->password_info['total_score'] = $total; + $this->password_info['rating_score'] = $rating_score; + $this->password_info['rating'] = $score_info; + + ksort($this->password_info); + ksort($this->password_info['details']); + } + + public function get_all_info() + { + return $this->password_info; + } + + public function get_score() + { + return $this->password_info['rating_score']; + } + + public function get_rating() + { + return $this->password_info['rating']; + } + + public function set_password($password) + { + $this->password = $password; + $this->password_length = strlen($password); + } + + private function calculate_charset_complexity() + { + $password = $this->password; + $len = strlen($password); + + $char = ''; + $last_char = ''; + $different_count = 0; + $score = 0; + + if ($len <= 3) + { + $score = 2; + } + else + { + for ($i = 0; $i < $len; $i++) + { + $char = substr($password, $i, 1); + if ($i > 0) + { + $last_char = substr($password, $i - 1, 1); + } + if ($char != $last_char) + { + $different_count++; + } + } + if ($len <= 5) + { + $score = 10; + } + else if ($different_count == 1) + { + $score = 1; + $this->password_info['details']['length_score'] = min(min(floor(10 * $this->password_length / 10), 20), $this->password_info['details']['length_score']); + } + else if ($different_count == 2) + { + $score = 5; + $this->password_info['details']['length_score'] = min(min(floor(20 * $this->password_length / 10), 40), $this->password_info['details']['length_score']); + } + else if ($different_count == 3) + { + $score = 10; + $this->password_info['details']['length_score'] = min(min(floor(30 * $this->password_length / 10), 50), $this->password_info['details']['length_score']); + } + else + { + $score = round(max($this->password_info['details']['length_score'] / 10, $different_count / $len * 100), $this->score_precision); + } + } + $this->password_info['details']['charset_complexity_score'] = $score; + } + + private function calculate_complexity() + { + $password = $this->password; + $score = 0; + + if (preg_match('/^([0-9]+)+$/', $password)) + { + $score = 10; + $this->password_info['details']['charset'] = 'numeric'; + } + else if (preg_match('/^([a-z]+)+$/', $password)) + { + $score = 30; + $this->password_info['details']['charset'] = 'alphabetic'; + } + else if (preg_match('/^([a-z0-9]+)+$/i', $password)) + { + if ((preg_match('/^([a-z]+)([0-9]+)+$/i', $password, $match)) || (preg_match('/^([0-9]+)([a-z]+)+$/i', $password, $match))) + { + $alpha = $match[1]; + $numeric = $match[2]; + $numeric_length = strlen($numeric); + + if (($numeric == 111) || ($numeric == 123)) + { + if (preg_match('/^([a-z]+)([0-9]+)+$/i', $password, $match)) + { + $score = 31; + } + else + { + $score = 35; + } + $this->password_info['details']['common_numeric'] = true; + } + else if ($numeric_length == 1) + { + $score = 30; + } + else if ($numeric_length <= 3) + { + $score = 35; + } + else if ($numeric_length <= 5) + { + $score = 40; + } + else if ($numeric_length <= 10) + { + $score = 50; + } + else + { + $score = 60; + } + $this->password_info['details']['charset'] = 'alphanumeric'; + } + else + { + $score = 80; + $this->password_info['details']['charset'] = 'alphanumeric'; + } + } + else + { + $score = 100; + $this->password_info['details']['charset'] = 'alphanumeric + others'; + } + $this->password_info['details']['charset_score'] = $score; + } + + private function calculate_length() + { + $len = $this->password_length; + $score = 0; + + if ($len == 0) + { + $score = 0; + } + else if ($len <= 3) + { + $score = 1; + } + else if ($len <= 4) + { + $score = 2; + } + else if ($len <= 5) + { + $score = 10; + } + else if ($len <= 6) + { + $score = 20; + } + else if ($len <= 8) + { + $score = 30; + } + else if ($len <= 10) + { + $score = 45; + } + else if ($len <= 15) + { + $score = 75; + } + else if ($len <= 18) + { + $score = 80; + } + else if ($len <= 20) + { + $score = 90; + } + else + { + $score = 100; + } + $this->password_info['details']['length_score'] = $score; + } + + private function calculate_entropy() + { + $score = 0; + $password = $this->password; + $length = $this->password_length; + + foreach (count_chars($password, 1) as $v) + { + $p = $v / $length; + $score -= $p * log($p)/log(2); + } + $this->password_info['details']['entropy_per_character'] = round($score, $this->score_precision); + $this->password_info['details']['entropy_score'] = round(($score * $length), $this->score_precision); + } + + private function get_score_info($score) + { + if ($score <= 15) + { + $score_info = 'Very Bad'; + } + else if ($score <= 35) + { + $score_info = 'Bad'; + } + else if ($score <= 45) + { + $score_info = 'Medium - Bad'; + } + else if ($score <= 55) + { + $score_info = 'Medium'; + } + else if ($score <= 65) + { + $score_info = 'Medium - Good'; + } + else if ($score <= 75) + { + $score_info = 'Good'; + } + else if ($score <= 90) + { + $score_info = 'Very Good'; + } + else + { + $score_info = 'Excellent'; + } + return $score_info; + } +} +?>