📜 ⬆️ ⬇️

PHP 5.5 "Password Hashing API"

Here is the final release of PHP 5.5.0. Briefly about the new features can be found in the post on the official website or "Translated into Russian . "

On Habré there were already articles about some of the new features of PHP 5.5.0, such as "Coroutines in PHP and working with non-blocking functions" and "In PHP 5.5, it will probably appear Finally"
This article will address one of the new features of PHP 5.5.0 "Password Hashing API ". Providing insured developers with errors and easier to use high-level functions for generating and checking the validity of passwords by hashes. The main difference between the new API is that it takes on the generation of reliable hashes, hiding from the developer the operation of manually specifying the salt and the choice of the hashing algorithm (Bcrypt is used by default). Creating a hash is reduced to running "$ hash = password_hash ($ password, PASSWORD_DEFAULT);", and checking for the call to "password_verify ($ password, $ hash)". The reason for the introduction of the new API was the careless attitude of many developers to the generation of salts and the ubiquitous selection of non-resistant to brute force hashing algorithms.

Constants, functions and code using them will be considered.

Predefined constants
The constants listed below are always available as part of the PHP core.
')
PASSWORD_BCRYPT (integer) = 1
PASSWORD_BCRYPT is used to create a new password hash using the CRYPT_BLOWFISH algorithm.

PASSWORD_DEFAULT (integer) = PASSWORD_BCRYPT
The default hashing algorithm is used if the algorithm is not specified. It may change in newer versions of PHP when new, more efficient (for example, Scrypt) hashing algorithms are supported.

Password Hash Functions




array password_get_info (string $ hash) - Returns information about this hash.

Returns an associative array with three elements (keys):
- algorithm ( algo ), which will correspond to the constant of the password algorithm ;
- the name of the algorithm ( algoName ), which has a human-readable name of the algorithm;
- associative array with options ( options ), which includes the possibilities provided by the password_hash () call.




string password_hash (string $ password, integer $ algo [, array $ options]) - creates a new password hash.

It returns an encrypted password or FALSE if an error occurs.




boolean password_needs_rehash (string $ hash, string $ algo [, string $ options]) - checks if the provided hash matches the specified algorithm and options. If not, it is considered that the hash should be changed.

Returns TRUE if the hash is to be changed to match the given algorithm and options, or FALSE otherwise.




boolean password_verify (string $ password, string $ hash) - Checks if the password matches the given hash. This hash can be created using password_hash () or a regular crypt () hash.

Returns TRUE if the password and hash match or FALSE otherwise.




Code and result output

<?php $options = [ 'cost' => 7, 'salt' => 'BCryptRequires22Chrcts', ]; $hash['hash'][] = password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options); //"$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq" $hash['hash'][] = password_hash("rasmuslerdorf", PASSWORD_DEFAULT); //"$2y$10$hHi0De9WN.HL6.Fz1ElvbOMIU5NA0tetwdJzNziKJvHFXFqOxsybi" $hash['info'][] = password_get_info($hash['hash'][0]); //array("algo" => 1 , "algoName" => "bcrypt" , "options" => array("cost" => 7 )) $hash['info'][] = password_get_info($hash['hash'][1]); //array("algo" => 1 , "algoName" => "bcrypt" , "options" => array("cost" => 10 )) $hash['rehash'][] = password_needs_rehash($hash['hash'][0],PASSWORD_BCRYPT,$options); //false $hash['rehash'][] = password_needs_rehash($hash['hash'][0],PASSWORD_DEFAULT); //true $hash['rehash'][] = password_needs_rehash($hash['hash'][1],PASSWORD_DEFAULT); //false $hash['pas_verify'][] = password_verify('rasmuslerdorf', $hash['hash'][0]); //true $hash['pas_verify'][] = password_verify('rasmuslerdorf', $hash['hash'][1]); //true $hash['pas_verify'][] = password_verify('rasmuslerdorff', $hash['hash'][0]); //false $hash['pas_verify'][] = password_verify('rasmuslerdorff', $hash['hash'][1]); //false var_dump($hash); 

Output
 array(4) { ["hash"]=> array(2) { [0] => string(60) "$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq" [1] => string(60) "$2y$10$CYb5tz9f5IVAgqX7SkIv9ufbi6yYlMQgAHcV4ixXjYSHJZl9KwLrK" } ["info"]=> array(2) { [0]=> array(3) { ["algo"] => int(1) ["algoName" ]=> string(6) "bcrypt" ["options"] => array(1) { ["cost"] => int(7) } } [1]=> array(3) { ["algo"] => int(1) ["algoName"] => string(6) "bcrypt" ["options"] => array(1) { ["cost"] => int(10) } } } ["rehash"]=> array(3) { [0] => bool(false) [1] => bool(true) [2] => bool(false) } ["pas_verify"]=> array(4) { [0] => bool(true) [1] => bool(true) [2] => bool(false) [3] => bool(false) } } 


Also on the site 3v4l.org you can see the VLD opcodes and comparative performance on different versions of PHP. For example, the performance of the code from the article.
VersionSystem timeUser timeMax. memory usage
5.5.0alpha10,018 s0,267 s12,152 MiB
5.5.0alpha20,018 s0,267 s12,148 MiB
5.5.0alpha30,015 s0,271 s12,148 MiB
5.5.0alpha40,019 s0,268 s12,164 MiB
5.5.0alpha50.014 s0,270 s12,195 MiB
5.5.0alpha60,016 s0,304 s12,219 MiB
5.5.0beta10,017 s0,270 s12,270 MiB
5.5.0beta20.027 s0,294 s12,270 MiB
5.5.0beta30.022 s0,265 s12,656 MiB
5.5.0beta40,016 s0,299 s12,656 MiB

Unfortunately, the final 5.5.0 release is not yet listed.

Possible future updates
At present, the default encryption algorithm (currently only one is supported) is determined by the preset constant PASSWORD_DEFAULT. In new versions of the language, the default encryption algorithm can be set in the settings.

In order to provide more effective protection, in subsequent versions of PHP, it is necessary to increase the algorithmic cost of calculating a password (BCrypt) - this will allow the password_hash () function to remain effective over time, with the improvement of technical equipment.

Future Fears
With the nature of cryptography, future compatibility is a matter of serious concern. In order to be safe, these functions will have to adapt to changing requirements in the future.

References:
Password Hashing API Documentation
Request for Comments: Adding simple password hashing API - Anthony Ferrara
Beta version of the new site PHP.net

PS from EugeneOZ :
These functions can be used now and without changing the code, switch to native ones.
Just need to use this file: github.com/ircmaxell/password_compat/blob/master/lib/password.php (PHP required = = 5.3.7)
Which is written by the same person who wrote the functions in PHP code - Anthony Ferrara

PS spelling errors and translation errors write to ps

Thanks:
thank
nixmale , newdya , how for the indicated errors.
EugeneOZ for the supplement.
@yourway for changing “Possible future updates” to a clearer version.

Source: https://habr.com/ru/post/184220/


All Articles