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:

Argon2 has three variants:

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.