2017 © Pedro Peláez
 

library password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

image

jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  • Tuesday, December 6, 2016
  • by jeremykendall
  • Repository
  • 9 Watchers
  • 143 Stars
  • 25,705 Installations
  • PHP
  • 4 Dependents
  • 0 Suggesters
  • 13 Forks
  • 4 Open issues
  • 18 Versions
  • 4 % Grown

The README.md

Password Validator Build Status Coverage Status

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords., (*1)

Read the introductory blog post: PHP Password Hashing: A Dead Simple Implementation, (*2)

Password Validator is available for all versions of PHP >= 5.3.7., (*3)

Motivation

Why? Because one must always encrypt passwords for highest level of security, and the new PHP password hashing functions provide that level of security., (*4)

The Password Validator library makes it (more) trivial to use the new password hash functions in your application. Just add the validator to your authentication script and you're up and running., (*5)

The really big deal here is the ease of upgrading from your current legacy hashes to the new, more secure PHP password hash hashes. Simply wrap the PasswordValidator in the UpgradeDecorator, provide a callback to validate your existing password hashing scheme, and BOOM, you're using new password hashes in a manner completely transparent to your application's users. Nifty, huh?, (*6)

Usage

Password Validation

If you're already using password_hash generated passwords in your application, you need do nothing more than add the validator in your authentication script. The validator uses password_verify to test the validity of the provided password hash., (*7)

``` php use JeremyKendall\Password\PasswordValidator;, (*8)

$validator = new PasswordValidator(); $result = $validator->isValid($_POST['password'], $hashedPassword);, (*9)

if ($result->isValid()) { // password is valid }, (*10)


If your application requires options other than the `password_hash` defaults, you can set the `cost` option with `PasswordValidator::setOptions()`. ``` php $options = array( 'cost' => 11 ); $validator->setOptions($options);

IMPORTANT: PasswordValidator uses a default cost of 10. If your existing hash implementation requires a different cost, make sure to specify it using PasswordValidator::setOptions(). If you do not do so, all of your passwords will be rehashed using a cost of 10., (*11)

Rehashing

Each valid password is tested using password_needs_rehash. If a rehash is necessary, the valid password is hashed using password_hash with the provided options. The result code Result::SUCCESS_PASSWORD_REHASHED will be returned from Result::getCode() and the new password hash is available via Result::getPassword()., (*12)

``` php if ($result->getCode() === Result::SUCCESS_PASSWORD_REHASHED) { $rehashedPassword = $result->getPassword(); // Persist rehashed password }, (*13)


**IMPORTANT**: If the password has been rehashed, it's critical that you persist the updated password hash. Otherwise, what's the point, right? ### Upgrading Legacy Passwords You can use the `PasswordValidator` whether or not you're currently using `password_hash` generated passwords. The validator will transparently upgrade your current legacy hashes to the new `password_hash` generated hashes as each user logs in. All you need to do is provide a validator callback for your password hash and then [decorate][6] the validator with the `UpgradeDecorator`. ``` php use JeremyKendall\Password\Decorator\UpgradeDecorator; // Example callback to validate a sha512 hashed password $callback = function ($password, $passwordHash, $salt) { if (hash('sha512', $password . $salt) === $passwordHash) { return true; } return false; }; $validator = new UpgradeDecorator(new PasswordValidator(), $callback); $result = $validator->isValid('password', 'password-hash', 'legacy-salt');

The UpgradeDecorator will validate a user's current password using the provided callback. If the user's password is valid, it will be hashed with password_hash and returned in the Result object, as above., (*14)

All password validation attempts will eventually pass through the PasswordValidator. This allows a password that has already been upgraded to be properly validated, even when using the UpgradeDecorator., (*15)

Alternate Upgrade Technique

Rather than upgrading each user's password as they log in, it's possible to preemptively rehash persisted legacy hashes all at once. PasswordValidator and the UpgradeDecorator can then be used to validate passwords against the rehashed legacy hashes, at which point the user's plain text password will be hashed with password_hash, completing the upgrade process., (*16)

For more information on this technique, please see Daniel Karp's Rehashing Password Hashes blog post, and review [JeremyKendall\Password\Tests\Decorator\KarptoniteRehashUpgradeDecoratorTest][11] to see a sample implementation., (*17)

Persisting Rehashed Passwords

Whenever a validation attempt returns Result::SUCCESS_PASSWORD_REHASHED, it's important to persist the updated password hash., (*18)

``` php if ($result->getCode() === Result::SUCCESS_PASSWORD_REHASHED) { $rehashedPassword = $result->getPassword(); // Persist rehashed password }, (*19)


While you can always perform the test and then update your user database manually, if you choose to use the **Storage Decorator** all rehashed passwords will be automatically persisted. The Storage Decorator takes two constructor arguments: An instance of `PasswordValidatorInterface` and an instance of the `JeremyKendall\Password\Storage\StorageInterface`. #### StorageInterface The `StorageInterface` includes a single method, `updatePassword()`. A class honoring the interface might look like this: ``` php <?php namespace Example; use JeremyKendall\Password\Storage\StorageInterface; class UserDao implements StorageInterface { public function __construct(\PDO $db) { $this->db = $db; } public function updatePassword($identity, $password) { $sql = 'UPDATE users SET password = :password WHERE username = :identity'; $stmt = $this->db->prepare($sql); $stmt->execute(array('password' => $password, 'identity' => $identity)); } }

Storage Decorator

With your UserDao in hand, you're ready to decorate a PasswordValidatorInterface., (*20)

``` php use Example\UserDao; use JeremyKendall\Password\Decorator\StorageDecorator;, (*21)

$storage = new UserDao($db); $validator = new StorageDecorator(new PasswordValidator(), $storage);, (*22)

// If validation results in a rehash, the new password hash will be persisted $result = $validator->isValid('password', 'passwordHash', null, 'username');, (*23)


**IMPORTANT**: You must pass the optional fourth argument (`$identity`) to `isValid()` when calling `StorageDecorator::isValid()`. If you do not do so, the `StorageDecorator` will throw an `IdentityMissingException`. #### Combining Storage Decorator with Upgrade Decorator It is possible to chain decorators together thanks to the [Decorator Pattern](https://en.wikipedia.org/wiki/Decorator_pattern). A great way to use this is to combine the `StorageDecorator` and `UpgradeDecorator` together to first update a legacy hash and then save it. Doing so is very simple - you just need to pass an instance of the `StorageDecorator` as a constructor argument to `UpgradeDecorator`: ``` php use Example\UserDao; use JeremyKendall\Password\Decorator\StorageDecorator; use JeremyKendall\Password\Decorator\UpgradeDecorator; // Example callback to validate a sha512 hashed password $callback = function ($password, $passwordHash, $salt) { if (hash('sha512', $password . $salt) === $passwordHash) { return true; } return false; }; $storage = new UserDao($db); $storageDecorator = new StorageDecorator(new PasswordValidator(), $storage); $validator = new UpgradeDecorator($storageDecorator, $callback); // If validation results in a rehash, the new password hash will be persisted $result = $validator->isValid('password', 'passwordHash', null, 'username');

Validation Results

Each validation attempt returns a JeremyKendall\Password\Result object. The object provides some introspection into the status of the validation process., (*24)

  • Result::isValid() will return true if the attempt was successful
  • Result::getCode() will return one of three possible int codes:
    • Result::SUCCESS if the validation attempt was successful
    • Result::SUCCESS_PASSWORD_REHASHED if the attempt was successful and the password was rehashed
    • Result::FAILURE_PASSWORD_INVALID if the attempt was unsuccessful
  • Result::getPassword() will return the rehashed password, but only if the password was rehashed

Database Schema Changes

As mentioned above, because this library uses the PASSWORD_DEFAULT algorithm, it's important your password field be VARCHAR(255) to account for future updates to the default password hashing algorithm., (*25)

Helper Scripts

After running composer install, there are two helper scripts available, both related to the password hash functions., (*26)

version-check

If you're not already running PHP 5.5+, you should run version-check to ensure your version of PHP is capable of using password-compat, the userland implementation of the PHP password hash functions. Run ./vendor/bin/version-check from the root of your project. The result of the script is pass/fail., (*27)

cost-check

The default cost used by password_hash is 10. This may or may not be appropriate for your production hardware, and it's entirely likely you can use a higher cost than the default. cost-check is based on the finding a good cost example in the PHP documentation. Simply run ./vendor/bin/cost-check from the command line and an appropriate cost will be returned., (*28)

NOTE: The default time target is 0.2 seconds. You may choose a higher or lower target by passing a float argument to cost-check, like so:, (*29)

``` bash $ ./vendor/bin/cost-check 0.4 Appropriate 'PASSWORD_DEFAULT' Cost Found: 13, (*30)


## Installation The only officially supported method of installation is via [Composer](http://getcomposer.org). Create a `composer.json` file in the root of your project (always check Packagist for the most recent version): ``` json { "require": { "jeremykendall/password-validator": "*" } }

And then run: composer install, (*31)

Add the autoloader to your project:, (*32)

``` php <?php, (*33)

require_once '../vendor/autoload.php' ```, (*34)

You're now ready to begin using the Password Validator., (*35)

Contributing

Pull requests are always welcome. Please review the CONTRIBUTING.md document before submitting pull requests., (*36)

The Versions

06/12 2016

dev-develop

dev-develop https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

26/01 2016

dev-master

9999999-dev https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

26/01 2016

3.0.4

3.0.4.0 https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

18/01 2016

dev-remove-salt

dev-remove-salt https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

25/03 2015

3.0.3

3.0.3.0 https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

18/09 2014

3.0.2

3.0.2.0 https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

14/05 2014

3.0.1

3.0.1.0 https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

14/05 2014

3.0.0

3.0.0.0 https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

15/02 2014

1.0.0

1.0.0.0 https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

15/02 2014

2.0.3

2.0.3.0 https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

15/02 2014

2.0.3-beta

2.0.3.0-beta https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

29/01 2014

2.0.2-beta

2.0.2.0-beta https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

12/01 2014

dev-feature/coveralls

dev-feature/coveralls https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

12/01 2014

2.0.1-beta

2.0.1.0-beta https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

11/01 2014

2.0.0-beta

2.0.0.0-beta https://github.com/jeremykendall/password-validator

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

security password passwords password_hash password validator password validation

11/01 2014

dev-dead-feature/phpass-implementation

dev-dead-feature/phpass-implementation

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

validator validation password upgrade password_hash rehash

05/01 2014

1.1.0-beta

1.1.0.0-beta

Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

validator validation password upgrade password_hash rehash

04/01 2014

1.0.0-beta

1.0.0.0-beta

Password Validator *validates* `password_hash` generated passwords, *rehashes* passwords as necessary, and will *upgrade* legacy passwords.

  Sources   Download

MIT

The Requires

 

The Development Requires

validator validation password upgrade password_hash rehash