Added objects for returning PasswordStrength results

This commit is contained in:
Zi Xing 2021-09-18 08:21:49 -04:00
parent c6515a9db9
commit 16246f3640
7 changed files with 375 additions and 46 deletions

View File

@ -28,7 +28,7 @@
SpatialMatch::class,
YearMatch::class
];
private $additionalMatchers = [];
/**

View File

@ -2,31 +2,34 @@
namespace Zxcvbn\Classes;
use Zxcvbn\Objects\EstimatedAttackTimes;
class TimeEstimator
{
/**
* @param $guesses
* @return array
* @return EstimatedAttackTimes
*/
public function estimateAttackTimes($guesses): array
public function estimateAttackTimes($guesses): EstimatedAttackTimes
{
$crack_times_seconds = [
'online_throttling_100_per_hour' => $guesses / (100 / 3600),
'online_no_throttling_10_per_second' => $guesses / 10,
'offline_slow_hashing_1e4_per_second' => $guesses / 1e4,
'offline_fast_hashing_1e10_per_second' => $guesses / 1e10
];
$return_results = new EstimatedAttackTimes();
$return_results->CrackTimesSeconds = new EstimatedAttackTimes\CrackTimes();
$crack_times_display = array_map(
[ $this, 'displayTime' ],
$crack_times_seconds
);
$return_results->CrackTimesSeconds->OnlineThrottling100PerHour = $guesses / (100 / 3600);
$return_results->CrackTimesSeconds->OnlineThrottling100PerHourDisplay =
$this->displayTime($return_results->CrackTimesSeconds->OnlineThrottling100PerHour);
$return_results->CrackTimesSeconds->OnlineNoThrottling10PerSecond = $guesses / 10;
$return_results->CrackTimesSeconds->OnlineNoThrottling10PerSecondDisplay =
$this->displayTime($return_results->CrackTimesSeconds->OnlineNoThrottling10PerSecond);
$return_results->CrackTimesSeconds->OfflineSlowHashing1e4PerSecond = $guesses / 1e4;
$return_results->CrackTimesSeconds->OfflineSlowHashing1e4PerSecondDisplay =
$this->displayTime($return_results->CrackTimesSeconds->OfflineSlowHashing1e4PerSecond);
$return_results->CrackTimesSeconds->OfflineFastHashing1e10PerSecond = $guesses / 1e10;
$return_results->CrackTimesSeconds->OfflineFastHashing1e10PerSecondDisplay =
$this->displayTime($return_results->CrackTimesSeconds->OfflineFastHashing1e10PerSecond);
return [
'crack_times_seconds' => $crack_times_seconds,
'crack_times_display' => $crack_times_display,
'score' => $this->guessesToScore($guesses)
];
$return_results->Score = $this->guessesToScore($guesses);
return $return_results;
}
/**

View File

@ -0,0 +1,102 @@
<?php
namespace Zxcvbn\Objects\EstimatedAttackTimes;
class CrackTimes
{
/**
* @var float|int
*/
public $OnlineThrottling100PerHour;
/**
* @var string
*/
public $OnlineThrottling100PerHourDisplay;
/**
* @var float|int
*/
public $OnlineNoThrottling10PerSecond;
/**
* @var string
*/
public $OnlineNoThrottling10PerSecondDisplay;
/**
* @var float|int
*/
public $OfflineSlowHashing1e4PerSecond;
/**
* @var string
*/
public $OfflineSlowHashing1e4PerSecondDisplay;
/**
* @var float|int
*/
public $OfflineFastHashing1e10PerSecond;
/**
* @var string
*/
public $OfflineFastHashing1e10PerSecondDisplay;
/**
* Returns an array representation of the object
*
* @return array
*/
public function toArray(): array
{
return [
'online_throttling_100_per_hour' => $this->OnlineThrottling100PerHour,
'online_throttling_100_per_hour_display' => $this->OnlineThrottling100PerHourDisplay,
'online_no_throttling_10_per_second' => $this->OnlineNoThrottling10PerSecond,
'online_no_throttling_10_per_second_display' => $this->OnlineNoThrottling10PerSecondDisplay,
'offline_slow_hashing_1e4_per_second' => $this->OfflineSlowHashing1e4PerSecond,
'offline_slow_hashing_1e4_per_second_display' => $this->OfflineSlowHashing1e4PerSecondDisplay,
'offline_fast_hashing_1e10_per_second' => $this->OfflineFastHashing1e10PerSecond,
'offline_fast_hashing_1e10_per_second_display' => $this->OfflineFastHashing1e10PerSecondDisplay
];
}
/**
* Constructs the object from an array representation
*
* @param array $data
* @return CrackTimes
*/
public static function fromArray(array $data): CrackTimes
{
$CrackTimesObject = new CrackTimes();
if(isset($data['online_throttling_100_per_hour']))
$CrackTimesObject->OnlineThrottling100PerHour = $data['online_throttling_100_per_hour'];
if(isset($data['online_throttling_100_per_hour_display']))
$CrackTimesObject->OnlineThrottling100PerHourDisplay = $data['online_throttling_100_per_hour_display'];
if(isset($data['online_no_throttling_10_per_second']))
$CrackTimesObject->OnlineNoThrottling10PerSecond = $data['online_no_throttling_10_per_second'];
if(isset($data['online_no_throttling_10_per_second_display']))
$CrackTimesObject->OnlineNoThrottling10PerSecondDisplay = $data['online_no_throttling_10_per_second_display'];
if(isset($data['offline_slow_hashing_1e4_per_second']))
$CrackTimesObject->OfflineSlowHashing1e4PerSecond = $data['offline_slow_hashing_1e4_per_second'];
if(isset($data['offline_slow_hashing_1e4_per_second_display']))
$CrackTimesObject->OfflineSlowHashing1e4PerSecondDisplay = $data['offline_slow_hashing_1e4_per_second_display'];
if(isset($data['offline_fast_hashing_1e10_per_second']))
$CrackTimesObject->OfflineFastHashing1e10PerSecond = $data['offline_fast_hashing_1e10_per_second'];
if(isset($data['offline_fast_hashing_1e10_per_second_display']))
$CrackTimesObject->OfflineFastHashing1e10PerSecondDisplay = $data['offline_fast_hashing_1e10_per_second_display'];
return $CrackTimesObject;
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace Zxcvbn\Objects;
use Zxcvbn\Objects\EstimatedAttackTimes\CrackTimes;
class EstimatedAttackTimes
{
/**
* The estimated times for how long this password could be cracked
*
* @var CrackTimes
*/
public $CrackTimesSeconds;
/**
* A display string of the crack times
*
* @var string
*/
public $CrackTimesDisplay;
/**
* The strength score of the password
*
* @var int
*/
public $Score;
/**
* Returns an array representation of the object
*
* @return array
*/
public function toArray(): array
{
return [
'crack_times_seconds' => $this->CrackTimesSeconds->toArray(),
'crack_times_display' => $this->CrackTimesDisplay,
'score' => $this->Score
];
}
public static function fromArray(array $data): EstimatedAttackTimes
{
$EstimatedAttackTimesObject = new EstimatedAttackTimes();
if(isset($data['crack_times_seconds']))
$EstimatedAttackTimesObject->CrackTimesSeconds = CrackTimes::fromArray($data['crack_times_seconds']);
if(isset($data['crack_times_display']))
$EstimatedAttackTimesObject->CrackTimesDisplay = $data['crack_times_display'];
if(isset($data['score']))
$EstimatedAttackTimesObject->Score = $data['score'];
return $EstimatedAttackTimesObject;
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace Zxcvbn\Objects;
class PasswordStrength
{
/**
* @var GuessableMatchSequence
*/
public $GuessableMatchSequence;
/**
* @var EstimatedAttackTimes
*/
public $EstimatedAttackTimes;
/**
* @var Feedback
*/
public $Feedback;
/**
* @var int
*/
public $Timelapse;
/**
* Returns an array representation of the object
*
* @return array
*/
public function toArray(): array
{
return [
'guessable_match_sequence' => $this->GuessableMatchSequence->toArray(),
'estimated_attack_times' => $this->EstimatedAttackTimes->toArray(),
'feedback' => $this->Feedback->toArray(),
'timelapse' => $this->Timelapse
];
}
/**
* Constructs the object from an array representation
*
* @param array $data
* @return PasswordStrength
*/
public static function fromArray(array $data): PasswordStrength
{
$PasswordStrengthObject = new PasswordStrength();
if(isset($data['guessable_match_sequence']))
$PasswordStrengthObject->GuessableMatchSequence = GuessableMatchSequence::fromArray($data['guessable_match_sequence']);
if(isset($data['estimated_attack_times']))
$PasswordStrengthObject->EstimatedAttackTimes = EstimatedAttackTimes::fromArray($data['estimated_attack_times']);
if(isset($data['feedback']))
$PasswordStrengthObject->Feedback = Feedback::fromArray($data['feedback']);
if(isset($data['timestamp']))
$PasswordStrengthObject->Timelapse = $data['timestamp'];
return $PasswordStrengthObject;
}
}

View File

@ -7,7 +7,14 @@
"organization": "Intellivoid Technologies",
"description": "Low-Budget Password Strength Estimation",
"url": "https://github.com/intellivoid/zxcvbn",
"dependencies": [],
"dependencies": [
{
"package": "net.intellivoid.timerlib",
"version": "latest",
"source": "default@github/intellivoid/TimerLib",
"required": true
}
],
"configuration": {
"autoload_method": "generated_spl",
"main": null,
@ -30,7 +37,23 @@
},
{
"required": true,
"file": "Classes/Matcher.php"
"file": "Classes/Utilities.php"
},
{
"required": true,
"file": "Classes/Matchers/SequenceMatch.php"
},
{
"required": true,
"file": "Classes/Matchers/YearMatch.php"
},
{
"required": true,
"file": "Classes/Matchers/RepeatMatch.php"
},
{
"required": true,
"file": "Classes/Matchers/DateMatch.php"
},
{
"required": true,
@ -38,7 +61,7 @@
},
{
"required": true,
"file": "Classes/Matchers/DateMatch.php"
"file": "Classes/Matchers/ReverseDictionaryMatch.php"
},
{
"required": true,
@ -48,37 +71,21 @@
"required": true,
"file": "Classes/Matchers/L33tMatch.php"
},
{
"required": true,
"file": "Classes/Matchers/RepeatMatch.php"
},
{
"required": true,
"file": "Classes/Matchers/ReverseDictionaryMatch.php"
},
{
"required": true,
"file": "Classes/Matchers/SequenceMatch.php"
},
{
"required": true,
"file": "Classes/Matchers/SpatialMatch.php"
},
{
"required": true,
"file": "Classes/Matchers/YearMatch.php"
},
{
"required": true,
"file": "Classes/Scorer.php"
},
{
"required": true,
"file": "Classes/TimeEstimator.php"
"file": "Classes/Matcher.php"
},
{
"required": true,
"file": "Classes/Utilities.php"
"file": "Classes/TimeEstimator.php"
},
{
"required": true,
@ -86,20 +93,32 @@
},
{
"required": true,
"file": "Objects/Feedback.php"
"file": "Objects/CrackTimes.php"
},
{
"required": true,
"file": "Objects/GuessableMatchSequence.php"
},
{
"required": true,
"file": "Objects/EstimatedAttackTimes.php"
},
{
"required": true,
"file": "Objects/PasswordStrength.php"
},
{
"required": true,
"file": "Objects/Feedback.php"
},
{
"required": true,
"file": "zxcvbn.php"
}
],
"files": [
"package.json",
"data/adjacency_graphs.json",
"data/frequency_lists.json",
"package.json"
"data/frequency_lists.json"
]
}

View File

@ -1,8 +1,88 @@
<?php
namespace Zxcvbn;
namespace Zxcvbn;
class zxcvbn
{
use TimerLib\Timer;
use Zxcvbn\Classes\FeedbackUtilities;
use Zxcvbn\Classes\Matcher;
use Zxcvbn\Classes\Scorer;
use Zxcvbn\Classes\TimeEstimator;
use Zxcvbn\Objects\Feedback;
use Zxcvbn\Objects\PasswordStrength;
}
class zxcvbn
{
/**
* @var Matcher
*/
protected $matcher;
/**
* @var Scorer
*/
protected $scorer;
/**
* @var TimeEstimator
*/
protected $timeEstimator;
/**
* @var FeedbackUtilities
*/
protected $feedback;
public function __construct()
{
$this->matcher = new Matcher();
$this->scorer = new Scorer();
$this->timeEstimator = new TimeEstimator();
$this->feedback = new Feedback();
}
/**
* @param string $className
* @return $this
* @noinspection PhpMissingReturnTypeInspection
*/
public function addMatcher(string $className)
{
$this->matcher->addMatcher($className);
return $this;
}
/**
* Calculate password strength via non-overlapping minimum entropy patterns.
*
* @param string $password Password to measure
* @param array $userInputs Optional user inputs
*
* @return PasswordStrength Strength result array with keys:
* @noinspection PhpUnused
*/
public function passwordStrength(string $password, array $userInputs = []): PasswordStrength
{
$timer = new Timer();
$timer->start();
$sanitizedInputs = array_map(
function ($input)
{
return mb_strtolower((string) $input);
},
$userInputs
);
$matches = $this->matcher->getMatches($password, $sanitizedInputs);
$return_results = new PasswordStrength();
$return_results->GuessableMatchSequence = $this->scorer->getMostGuessableMatchSequence($password, $matches);
$return_results->EstimatedAttackTimes = $this->timeEstimator->estimateAttackTimes($return_results->GuessableMatchSequence->Guesses);
$return_results->Feedback = $this->feedback->getFeedback(
$return_results->EstimatedAttackTimes->Score, $return_results->GuessableMatchSequence->Sequence
);
$return_results->Timelapse = $timer->stop()->getMilliseconds();
return $return_results;
}
}