Realistic PHP password strength estimate library based on Zxcvbn JS

Related tags

zxcvbn-php
Overview

Zxcvbn-PHP is a password strength estimator using pattern matching and minimum entropy calculation. Zxcvbn-PHP is based on the the Javascript zxcvbn project from Dropbox and @lowe. "zxcvbn" is bad password, just like "qwerty" and "123456".

zxcvbn attempts to give sound password advice through pattern matching and conservative entropy calculations. It finds 10k common passwords, common American names and surnames, common English words, and common patterns like dates, repeats (aaa), sequences (abcd), and QWERTY patterns.

Build Status Coverage Status Latest Stable Version License

Installation

The library can be installed with Composer by adding it as a dependency to your composer.json file.

Via the command line run: composer require bjeavons/zxcvbn-php

Or in your composer.json add

{
    "require": {
        "bjeavons/zxcvbn-php": "^1.0"
    }
}

Then run composer update on the command line and include the autoloader in your PHP scripts so that the ZxcvbnPhp class is available.

require_once 'vendor/autoload.php';

Usage

use ZxcvbnPhp\Zxcvbn;

$userData = [
  'Marco',
  '[email protected]'
];

$zxcvbn = new Zxcvbn();
$weak = $zxcvbn->passwordStrength('password', $userData);
echo $weak['score']; // will print 0

$strong = $zxcvbn->passwordStrength('correct horse battery staple');
echo $strong['score']; // will print 4

echo $weak['feedback']['warning']; // will print user-facing feedback on the password, set only when score <= 2
// $weak['feedback']['suggestions'] may contain user-facing suggestions to improve the score

Scores are integers from 0 to 4:

  • 0 means the password is extremely guessable (within 10^3 guesses), dictionary words like 'password' or 'mother' score a 0
  • 1 is still very guessable (guesses < 10^6), an extra character on a dictionary word can score a 1
  • 2 is somewhat guessable (guesses < 10^8), provides some protection from unthrottled online attacks
  • 3 is safely unguessable (guesses < 10^10), offers moderate protection from offline slow-hash scenario
  • 4 is very unguessable (guesses >= 10^10) and provides strong protection from offline slow-hash scenario

Acknowledgements

Thanks to:

Issues
  • Discrepancy with original Dropbox JS library

    Discrepancy with original Dropbox JS library

    The phrase nothingtoshare scores a 3 on the JS library (can check with https://dl.dropboxusercontent.com/u/209/zxcvbn/test/index.html). However, this version gives a score of 0:

    $strength = {array} [6]
     crack_time = 18.85575
     calc_time = 0.031842947006226
     password = "nothingtoshare"
     entropy = 18.524645010213
     match_sequence = {array} [3]
     score = 0
    

    Similarly [email protected] also scores 3, but only a 1 here:

    $strength = {array} [6]
     crack_time = 509.10525
     calc_time = 0.059408903121948
     password = "[email protected]"
     entropy = 23.279532512376
     match_sequence = {array} [3]
      0 = {ZxcvbnPhp\Matchers\L33tMatch} [13]
       sub = {array} [3]
       subDisplay = "0 -> o, 1 -> i, 0 -> o, @ -> a"
       l33t = true
       dictionaryName = "english"
       rank = 155
       matchedWord = "nothing"
       password = "[email protected]"
       begin = 0
       end = 6
       token = "n0th1ng"
       pattern = "dictionary"
       entropy = null
       cardinality = null
      1 = {ZxcvbnPhp\Matchers\L33tMatch} [13]
      2 = {ZxcvbnPhp\Matchers\L33tMatch} [13]
     score = 1
    

    Not sure if the issue is here or with the DropBox lib.

    opened by aramonc 32
  • Implement features added to the original version

    Implement features added to the original version

    Will those features that are added the last 4 years to the original version also be added to this one?

    opened by Mondane 17
  • Add custom matcher

    Add custom matcher

    opened by AlexLisenkov 6
  • Add php-7.4 and nightly version tests

    Add php-7.4 and nightly version tests

    Changed log

    • Add the php-7.4 and php-nightly tests.
    • Let php-nightly allow to be failed because nobody can guarantee that unstable PHP version will be successful on every Travis CI build.
    opened by peter279k 4
  • Added 2 more tests, 1 failing

    Added 2 more tests, 1 failing

    The final test is currently failing however. See issue #9

    opened by SteveEdson 4
  • Fix user inputs incorrectly affecting scores

    Fix user inputs incorrectly affecting scores

    Case 1: User input having named keys

    It's not uncommon to want to take things like a user's name, username, email address, and other user metadata into account when evaluating password strength. These items may already already be available in a string-keyed array such as ['name' => 'bob', 'email' => '[email protected]']. The present implementation will use the string key as the input rank, which causes an error when attempting to take the log() of it.

    This is fixed by setting the rank of any user input that has a string key to whatever its numerical position in the user input array is.

    Case 2: Matching user input with rank 0 scoring incorrectly

    correct horse battery staple with no user input would score a 4, but the same password with ['c'] as the user input changes the score to 0 (which is obviously not correct). This is because a rank of 0 causes an entropy score of -INF, which causes the crack time to evaluate to 0.

    This is fixed by ensuring the minimum rank that can be assigned to a value is 1. Any reasonable number would work, but 1 seemed like a fair default, since the default behavior is to use the array index, and 1 is the lowest nonzero positive integer.

    opened by michaelmoussa 4
  • Add user data usage example to readme

    Add user data usage example to readme

    Without documented usage of user data argument, php devs would default to passing the array such as

    ['Marco', '[email protected]']
    

    which fails at dictionary matcher when computing a logarithm of string.

    opened by Mikulas 3
  • Uncaught Error: [] operator not supported for strings

    Uncaught Error: [] operator not supported for strings

    PHP Fatal error: Uncaught Error: [] operator not supported for strings in /vendor/bjeavons/zxcvbn-php/src/Matchers/L33tMatch.php:55

    any ideas how to fix this ?

    I'm running PHP 7.1.0

    I already try : $result['sub_display'][] = "{$password[$i]} -> $t";

    but I keep getting the same error :(

    Stack trace:
    #0 //vendor/bjeavons/zxcvbn-php/src/Matcher.php(27): ZxcvbnPhp\Matchers\L33tMatch::match('[email protected]$$', Array)
    #1 //vendor/bjeavons/zxcvbn-php/src/Zxcvbn.php(53): ZxcvbnPhp\Matcher->getMatches('[email protected]$$', Array)
    #2 //vendor/phpauth/phpauth/Auth.php(187): ZxcvbnPhp\Zxcvbn->passwordStrength('[email protected]$$')
    #3 /index.php(25): PHPAuth\Auth->register('[email protected]', '[email protected]$$', '[email protected]$$')
    #4 {main}
      thrown in //vendor/bjeavons/zxcvbn-php/src/Matchers/L33tMatch.php on line 55
    
    opened by fidel95 3
  • Password score from JavaScript ist not the same

    Password score from JavaScript ist not the same

    Hi, the password score of JavaScript is not the same as in PHP. I guess that should not be like that?

    PHP

    array:6 [
      "password" => "1111"
      "score" => 0
    ]
    array:6 [
      "password" => "Monday"
      "score" => 0
    ]
    array:6 [
      "password" => "Mond!ay"
      "score" => 2
    ]
    

    JavaScript

    {
      "password": "111",
      "score": 0
    }
    {
      "password": "Monday",
      "score": 1
    }
    {
      "password": "Mond!ay",
      "score": 2
    }
    
    opened by Cyb10101 2
  • [feature] Dictionnary location

    [feature] Dictionnary location

    Hello,

    Dictionary location is hard-coded in code. As I'm using composer to install/update, I can't update it. Could you please allow a parameter to be able to specify dictionary location?

    thanks

    opened by abonne01 0
  • [feature] Add Timeout for long execution

    [feature] Add Timeout for long execution

    Hello,

    I'm scanning with this lib all my passwords. But tome of them are token/keys, which are quite long. Analyze them can take sometimes more than 30min.

    Could you add timeout parameter? or a check for length ?

    Thanks a lot.

    opened by abonne01 0
  • feat: add feedback warning code to response array

    feat: add feedback warning code to response array

    Actions #54

    Adds a 'code' element to the response array in order to allow developers to map the weakness reason in a consistent way to a more suitable message for the specific application (e.g. to alter tone of voice or language).

    opened by hannahtinkler 0
  • Add warning code to response array to allow mapping to custom feedback strings

    Add warning code to response array to allow mapping to custom feedback strings

    As a developer I want to be able to identify the reason for a low score using a concise string which will never change So that I can communicate the feedback to my users in way which is more consistent with my application/brand tone of voice/localisation requirements

    If a consistent response code was part of the response array, this would allow developers to map this to localisation maps and create validation messages which flow in a way that better suits their application. This is different to the feedback warnings currently returned which aren't guaranteed to not change in style/content (and so can't be mapped directly without risking breaking functionality with future updates).

    Example:

    [
      'password' =>'hannah2021',
      'guesses' => 2.13811968952E+20,
      'guesses_log10' =>20.330032012867,
      'sequence' => [...],
      'crack_times_seconds' => [...],
      'crack_times_display' => [...],
      'score' => 4,
      'feedback' => [
        'warning' => 'Dates are often easy to guess',
        'suggestion' => [...],
        'code' => 'guessable_dates',
      ],
      'calc_time' => 0.0208580493927,
    ]
    

    Which would allow mapping to languages:

    translate(sprintf('en.%s', $response['feedback']['code']));
    

    Or mapping to custom messages:

    private $map = [
        'guessable_dates' => 'Increase the complexity of your password or consider omitting dates from it.',
    ];
    
    
    public function message()
    {
        return $this->map[$response['feedback']['code']];
    }
    
    opened by hannahtinkler 0
  • List/doc over what is min,. requirement to reach X score

    List/doc over what is min,. requirement to reach X score

    List/doc over what is min,. requirement to reach X score.

    • So it's easier to choose which fits the best.
    opened by Conver 0
  • Symfony Bundle Reference

    Symfony Bundle Reference

    Hello maintainers,

    I've been working on a symfony bundle that enables localization and tagging matchers in symfony. How do you feel about referencing https://github.com/createnl/zxcvbn-bundle in the readme for people that use symfony?

    opened by AlexLisenkov 5
  • Add warning from user input

    Add warning from user input

    When the user input is the main cause, the warning message was empty.

    I added one, but since I'm not a native speaker (as you can notice 😬), any suggestion for the message is more than welcome.

    I also added some phpstan doc: https://phpstan.org/r/68533b15-9d58-4205-9a0f-5664c8aca3fe

    opened by franmomu 2
  • add static analysis to the project

    add static analysis to the project

    It will be useful to add psalm\phpstan to the project to make it more strict.

    opened by vladyslavstartsev 0
  • array_unique error

    array_unique error

    ErrorException: 2: array_unique() expects parameter 1 to be array, bool given in

    ... /vendor/bjeavons/zxcvbn-php/src/Matchers/L33tMatch.php(138): array_unique(false)

    opened by tomsommer 1
  • Ability to disable DictionaryMatch as customization

    Ability to disable DictionaryMatch as customization

    Hi,

    Would like to know if we can disable Dictionary Match as an optional customization? I tried disabling it by commenting the invocation of Matchers\DictionaryMatch::class, in getMatchers() function of Matcher.php file. Just wanted to know if there's another option or this is the only one I could use here?

    Note: I don't want to alter contents of ranked_frequency_lists.json file.

    opened by raror3 0
Releases(1.2.0)
Owner
Ben Jeavons
Ben Jeavons
A library for generating and validating passwords

PHP-PasswordLib Build Status Version The current version is considered Beta. This means that it is ready enough to test and use, but beware that you s

Anthony Ferrara 372 Jul 7, 2021
PHP Library to generate random passwords

Password Generator Library Simple library for generating random passwords. Requirements PHP >= 7.1 We only support PHP 7.3+ Installation Install Compo

Daniel Platt 235 Sep 7, 2021
Compatibility with the password_* functions that ship with PHP 5.5

password_compat This library is intended to provide forward compatibility with the password_* functions that ship with PHP 5.5. See the RFC for more d

Anthony Ferrara 2.1k Sep 7, 2021
A password policy enforcer for PHP and JavaScript

PasswordPolicy A tool for checking and creating password policies in PHP and JS. Installation Use composer to setup an autoloader php composer.phar in

Anthony Ferrara 71 Jul 3, 2021
Python implementation of the portable PHP password hashing framework

Portable PHP password hashing framework implemented in Python. This Python implementation meant to be an exact port of the the original PHP version.

Rez 46 Nov 25, 2019
GenPhrase is a secure passphrase generator for PHP applications.

About GenPhrase is a secure passphrase generator for PHP applications. GenPhrase is based on passwdqc's pwqgen program. See http://www.openwall.com/pa

timoh 94 Aug 29, 2021