[php] How do you use bcrypt for hashing passwords in PHP?

Here's an updated answer to this old question!

The right way to hash passwords in PHP since 5.5 is with password_hash(), and the right way to verify them is with password_verify(), and this is still true in PHP 8.0. These functions use bcrypt hashes by default, but other stronger algorithms have been added. You can alter the work factor (effectively how "strong" the encryption is) via the password_hash parameters.

However, while it's still plenty strong enough, bcrypt is no longer considered state-of-the-art; a better set of password hash algorithms has arrived called Argon2, with Argon2i, Argon2d, and Argon2id variants. The difference between them (as described here):

Argon2 has one primary variant: Argon2id, and two supplementary variants: Argon2d and Argon2i. Argon2d uses data-depending memory access, which makes it suitable for cryptocurrencies and proof-of-work applications with no threats from side-channel timing attacks. Argon2i uses data-independent memory access, which is preferred for password hashing and password-based key derivation. Argon2id works as Argon2i for the first half of the first iteration over the memory, and as Argon2d for the rest, thus providing both side-channel attack protection and brute-force cost savings due to time-memory tradeoffs.

Argon2i support was added in PHP 7.2, and you request it like this:

$hash = password_hash('mypassword', PASSWORD_ARGON2I);

and Argon2id support was added in PHP 7.3:

$hash = password_hash('mypassword', PASSWORD_ARGON2ID);

No changes are required for verifying passwords since the resulting hash string contains information about what algorithm, salt, and work factors were used when it was created.

Quite separately (and somewhat redundantly), libsodium (added in PHP 7.2) also provides Argon2 hashing via the sodium_crypto_pwhash_str () and sodium_crypto_pwhash_str_verify() functions, which work much the same way as the PHP built-ins. One possible reason for using these is that PHP may sometimes be compiled without libargon2, which makes the Argon2 algorithms unavailable to the password_hash function; PHP 7.2 and higher should always have libsodium enabled, but it may not - but at least there are two ways you can get at that algorithm. Here's how you can create an Argon2id hash with libsodium (even in PHP 7.2, which otherwise lacks Argon2id support)):

$hash = sodium_crypto_pwhash_str(
    'mypassword',
    SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);

Note that it doesn't allow you to specify a salt manually; this is part of libsodium's ethos – don't allow users to set params to values that might compromise security – for example there is nothing preventing you from passing an empty salt string to PHP's password_hash function; libsodium doesn't let you do anything so silly!

Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to passwords

Your password does not satisfy the current policy requirements Laravel Password & Password_Confirmation Validation Default password of mysql in ubuntu server 16.04 mcrypt is deprecated, what is the alternative? What is the default root pasword for MySQL 5.7 MySQL user DB does not have password columns - Installing MySQL on OSX Changing an AIX password via script? Hide password with "•••••••" in a textField How to create a laravel hashed password Enter export password to generate a P12 certificate

Examples related to cryptography

Failed to install Python Cryptography package with PIP and setup.py C# RSA encryption/decryption with transmission How do you Encrypt and Decrypt a PHP String? Example of AES using Crypto++ How to encrypt/decrypt data in php? How to decrypt a SHA-256 encrypted string? Simplest two-way encryption using PHP Padding is invalid and cannot be removed? Given final block not properly padded Getting RSA private key from PEM BASE64 Encoded private key file

Examples related to password-protection

SQLite with encryption/password protection How do you use bcrypt for hashing passwords in PHP? Easy way to password-protect php page Where does Internet Explorer store saved passwords? HTTP authentication logout via PHP Removing the password from a VBA project

Examples related to bcrypt

How to decrypt hash stored by bcrypt Unable to install gem - Failed to build gem native extension - cannot load such file -- mkmf (LoadError) How can bcrypt have built-in salts? What column type/length should I use for storing a Bcrypt hashed password in a Database? How do you use bcrypt for hashing passwords in PHP?