Download the PHP package jeremykendall/password-validator without Composer
On this page you can find all versions of the php package jeremykendall/password-validator. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download jeremykendall/password-validator
More information about jeremykendall/password-validator
Files in jeremykendall/password-validator
Package password-validator
Short Description Password Validator validates password_hash generated passwords, rehashes passwords as necessary, and will upgrade legacy passwords.
License MIT
Homepage https://github.com/jeremykendall/password-validator
Informations about the package password-validator
Password Validator
Password Validator validates password_hash
generated passwords, rehashes
passwords as necessary, and will upgrade legacy passwords.
Read the introductory blog post: PHP Password Hashing: A Dead Simple Implementation
Password Validator is available for all versions of PHP >= 5.3.7.
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.
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.
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?
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.
If your application requires options other than the password_hash
defaults,
you can set the cost
option with PasswordValidator::setOptions()
.
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
.
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()
.
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 the validator with the UpgradeDecorator
.
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.
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
.
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.
For more information on this technique, please see Daniel Karp's
Rehashing Password Hashes blog post, and review
JeremyKendall\Password\Tests\Decorator\KarptoniteRehashUpgradeDecoratorTest
to see a sample implementation.
Persisting Rehashed Passwords
Whenever a validation attempt returns Result::SUCCESS_PASSWORD_REHASHED
, it's
important to persist the updated password hash.
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:
Storage Decorator
With your UserDao
in hand, you're ready to decorate a
PasswordValidatorInterface
.
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. 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
:
Validation Results
Each validation attempt returns a JeremyKendall\Password\Result
object. The
object provides some introspection into the status of the validation process.
Result::isValid()
will returntrue
if the attempt was successfulResult::getCode()
will return one of three possibleint
codes:Result::SUCCESS
if the validation attempt was successfulResult::SUCCESS_PASSWORD_REHASHED
if the attempt was successful and the password was rehashedResult::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.
Helper Scripts
After running composer install
, there are two helper scripts available, both
related to the password hash functions.
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.
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.
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:
Installation
The only officially supported method of installation is via Composer.
Running the following command will add the latest version of the library to your project:
You can update to the latest version with this command:
If you're not already using Composer in your project, add the autoloader to your project:
You're now ready to begin using the Password Validator.
Contributing
Pull requests are always welcome. Please review the CONTRIBUTING.md document before submitting pull requests.
All versions of password-validator with dependencies
ircmaxell/password-compat Version 1.*
wp-cli/php-cli-tools Version 0.10.*