New Hashing Algorithm for Passwords
When it comes to storing passwords, saving them as a
cryptographically secure hash rather than its plain text version is
a key requirement for any up-to-date web application. Since PHP 5.5,
the functions password_hash()
and
password_verify()
help with that.
By default, the Blowfish algorithm will be used to hash the
passwords. Blowfish was originally designed in 1993 and does not
support passwords that have more than 72 characters. Password
arguments passed to password_hash()
and
password_verify()
will be truncated to a maximum length
of 72 characters when the Blowfish algorithm is used.
Argon2, the winner of the 2015 Password Hashing Competition, is supported since PHP 7.2. Unlike Blowfish, which just takes a single cost factor, Argon2 is parameterized by three distinct factors:
- A cost factor in bytes to define memory usage (default: 1024)
- A time cost factor to define the execution time and the number of iterations (default: 2)
- A parallelism factor to control the number of parallel threads (default: 2)
Argon2 has three variants:
- Argon2d (not supported by PHP): fast, highly resistant against GPU cracking attacks, suitable for applications with no threats from side-channel timing attacks
- Argon2i (supported since PHP 7.2): slow, makes more passes over the memory to protect from tradeoff attacks
- Argon2id (supported since PHP 7.3): hybrid of Argon2i and Argon2d
Argon2id is the recommended Argon2 variant to use. With default arguments, it can be used like so:
$hash = password_hash('password', PASSWORD_ARGON2ID);
var_dump($hash);
The resulting output will look something like this:
string(97) "$argon2id$v=19$m=65536,t=4,p=1$YkJ...84ew"
As always with password_hash()
, the default options
can also be overwritten using the third parameter:
$options = [
'memory_cost' => 2048,
'time_cost' => 4,
'threads' => 3
];
$hash = password_hash('password', PASSWORD_ARGON2ID, $options);
var_dump($hash);
This version yields the following output:
string(96) "$argon2id$v=19$m=2048,t=4,p=3$RXhW...vpbI"
PHP can use two different implementations of the Argon2
algorithms: libargon2
and libsodium
. When
the ext/sodium
extension is loaded then the
libsodium
implementation is used. When the
ext/sodium
extension is not loaded and PHP was built
with --with-password-argon2
then the
libargon2
implementation is used.
The libsodium
implementation is recommended over the
libargon2
one for performance and other reasons.