Reference
Password
In the Laminas\Crypt\Password
namespace you will find a number of password
formats supported by the laminas-crypt component. These currently include:
- bcrypt
- Apache (htpasswd)
If you need to choose a password format to store a user’s password, we suggest using the bcrypt algorithm, as it is considered secure against brute forcing attacks (see details below).
Bcrypt
The bcrypt algorithm is a hashing algorithm that is widely used and recommended by the security community to store user passwords in a secure way.
Classic hashing mechanisms like MD5 or SHA, with or without a salt value, are not considered secure anymore (read this post to understand why).
The security of bcrypt is related to the speed of the algorithm. Bcrypt is very slow, and can take up to a second to generate a hash value. That means a brute force attack is impossible to execute, due to the amount of time that required.
Bcrypt uses a cost parameter that specify the number of cycles to use in the
algorithm. Increasing this number the algorithm will spend more time to generate
the hash output. The cost parameter is represented by an integer value between 4
to 31. The default cost value of Laminas\Crypt\Password\Bcrypt
is 10, requiring
around 0.07s using a CPU Intel i5 at 3.3Ghz (the cost parameter is a relative
value according to the speed of the CPU used). Starting with version 2.3.0, we
changed the default value of the cost parameter from 14 to 10, in an effort to
reduce denial-of-service attacks due to too high computational time
requirements. (Read this article on aggressive password stretching
for more information).
If you want to change the cost parameter of the bcrypt algorithm, you can use
the setCost()
method. Please note, if you change the cost parameter, the
resulting hash will be different. However, This will not affect the verification
process of the algorithm, therefore not breaking the password hashes you already
have stored; Bcrypt reads the cost parameter from the hash value during password
authentication. All of the parts needed to verify the hash are present in the
hash itself,, separated with $
’s; first the algorithm, then the cost, the
salt, and then finally the hash.
The example below demonstrates using the bcrypt algorithm to store a user’s password:
use Laminas\Crypt\Password\Bcrypt;
$bcrypt = new Bcrypt();
$securePass = $bcrypt->create('user password');
The output of the create()
method is the hash of the password. This value can
then be stored in a repository like a database (the output is a string of 60
bytes).
Bcrypt truncates Input > 72 bytes
The input string of the bcrypt algorithm is limited to 72 bytes. If you use a string with a length more than this limit, bcrypt will consider only the first 72 bytes. If you need to use a longer string, you should pre-hash it. We provide the class
Laminas\Crypt\Password\BcryptSha
for performing password pre-hashing of hash input > 72 bytes.
To verify if a given password is valid against a bcrypt value you can use the
verify()
method. The example below demonstrates verification:
use Laminas\Crypt\Password\Bcrypt;
$bcrypt = new Bcrypt();
$securePass = 'the stored bcrypt value';
$password = 'the password to check';
if ($bcrypt->verify($password, $securePass)) {
echo "The password is correct! \n";
} else {
echo "The password is NOT correct.\n";
}
Bcrypt also uses a salt value to improve the randomness of the algorithm.
By default, Laminas\Crypt\Password\Bcrypt
generates a random salt for
each hash. If you want to specify a preselected salt you can use the setSalt()
method.
We also provide a getSalt()
method to retrieve the salt specified by the user.
The salt and the cost parameter can be also specified during the constructor of
the class, as demonstrated below:
use Laminas\Crypt\Password\Bcrypt;
$bcrypt = new Bcrypt([
'salt' => 'random value',
'cost' => 11
]);
Version 3.0
Starting with version 3.0, we now use the password_hash() and `password_verify() functions introduced in PHP 5.5 to generate bcrypt hash values. We provide backwards compatibility tests to ensure that any hashes generated with version 2 releases can still be validated under version 3.
Apache
Laminas\Crypt\Password\Apache
supports all the password formats used by
Apache
(htpasswd). These formats include:
- CRYPT, which uses the traditional Unix crypt(3) function with a randomly-generated 32-bit salt (only 12 bits used) and the first 8 characters of the password;
- SHA1, “{SHA}” + Base64-encoded SHA-1 digest of the password;
- MD5, “$apr1$” + the result of an Apache-specific algorithm using an iterated (1,000 times) MD5 digest of various combinations of a random 32-bit salt and the password.
- Digest, the MD5 hash of the string
user:realm:password
as a 32-character string of hexadecimal digits.realm
is the Authorization Realm argument to the AuthName directive inhttpd.conf
.
In order to specify the format of the Apache’s password, use the setFormat()
method. An example with all the formats usage is demonstrated below:
use Laminas\Crypt\Password\Apache;
$apache = new Apache();
$apache->setFormat('crypt');
printf ("CRYPT output: %s\n", $apache->create('password'));
$apache->setFormat('sha1');
printf ("SHA1 output: %s\n", $apache->create('password'));
$apache->setFormat('md5');
printf ("MD5 output: %s\n", $apache->create('password'));
$apache->setFormat('digest');
$apache->setUserName('enrico');
$apache->setAuthName('test');
printf ("Digest output: %s\n", $apache->create('password'));
You can also specify the format of the password during the constructor of the class:
use Laminas\Crypt\Password\Apache;
$apache = new Apache([
'format' => 'md5'
]);
Other possible parameters to pass in the constructor are username
and authname
,
for the digest format.
Found a mistake or want to contribute to the documentation? Edit this page on GitHub!