- PVSM.RU - https://www.pvsm.ru -

PHP 5.5 «API хэширования паролей»

Вот и вышел финальный релиз PHP 5.5.0. Кратко о новых возможностях можно прочитать в посте на официальном сайте [1] или «Переведенное на русский» [2].

На хабре уже были статьи о некоторых новых возможностях PHP 5.5.0, такие как «Coroutines в PHP и работа с неблокирующими функциями» [3] и «В PHP 5.5 возможно появится Finally» [4]
В данной статье будет затронута одна из новых возможностей PHP 5.5.0 "API хэширования паролей" [5].Предоставляющий застрахованные от ошибок разработчиков и более простые в использовании высокоуровневые функции для генерации и проверки валидности паролей по хэшам. Основное отличие нового API в том, что он берёт на себя генерацию надёжных хэшей, скрывая от разработчика операции ручного указания salt-а и выбора алгоритма хэширования (по умолчанию используется Bcrypt). Создание хэша сведено к выполнению "$hash = password_hash($password, PASSWORD_DEFAULT);", а проверка к вызову «password_verify($password, $hash)». В качестве причины внедрения нового API послужило безалаберное отношение многих разработчиков к генерации salt-ов и повсеместный выбор нестойких к перебору алгоритмов хэширования.

Будут рассмотрены константы, функции и код использующий их.

Предопределенные константы
Перечисленные ниже константы всегда доступны как часть ядра PHP.

PASSWORD_BCRYPT (integer) = 1
PASSWORD_BCRYPT используется для создания нового хэш пароля с использованием алгоритма CRYPT_BLOWFIS [6].

PASSWORD_DEFAULT (integer) = PASSWORD_BCRYPT
Используется алгоритм хэширования по умолчанию если алгоритм не задан. Он может измениться в новых версиях PHP, когда будут поддерживаться новые, более эффективные (например, Scrypt) алгоритмы хэширования.

Функции хэширования паролей


array password_get_info ( string $hash ) — Возвращает информацию о данном хэше.

  • hash — хэш, созданный функцией password_hash() [7].

Возвращает ассоциативный массив с тремя элементами(ключами):
— алгоритм(algo), который будет соответствовать константе алгоритма пароля [8];
— название алгоритма(algoName), которое имеет человечески читаемое название алгоритма;
— ассоциативный массив с опциями (options), который включает в себя возможности, предоставляемые при вызове password_hash () [7].


string password_hash ( string $password, integer $algo [, array $options ] ) — создает новый хэш пароля.

  • password-пользовательский пароль.
  • algo — константа [8], обозначающая используемый алгоритм хэширования пароля. Вы можете использовать алгоритм по умолчанию постоянно, если вы хотите, чтобы алгоритм автоматически обновлялся в более эффективный, доступный в новых версиях PHP.
  • options — ассоциативный массив с опциями. В данный момент поддерживаются только 2 опции: salt — соль, используемая при хэшировании пароля, и cost, обозначающая алгоритмическую стоимость вычисления пароля. Примеры данных значений можно найти на странице документации функции crypt() [6]. Если он опущен, будет создана случайная соль и будет использоваться алгоритмическая стоимость вычисления по умолчанию.

Возвращает зашифрованный пароль или FALSE в случае возникновения ошибки.


boolean password_needs_rehash ( string $hash, string $algo [, string $options ] ) — проверяет, соответствуетли предоставленныйхэшзаданномуалгоритмуиопциям. Еслинет, тосчитается, чтохэшдолжнбытьизменён.

  • hash — хэш, созданныйфункцией password_hash() [7].
  • algo — константа [8], обозначающая используемый алгоритм хэширования пароля.
  • options — ассоциативный массив с опциями. В данный момент поддерживаются только 2 опции: salt — соль, используемая при хэшировании пароля, и cost, обозначающая алгоритмическую стоимость вычисления пароля. Примеры данных значений можно найти на странице документации функции crypt() [6]. Если он опущен, будет использоваться алгоритмическая стоимость вычисления по умолчанию.

Возвращает TRUE, если хэш должн быть изменён, чтобы соответствовать данному алгоритму и опциям, или в противном случае FALSE.


boolean password_verify ( string $password, string $hash ) — Проверяет, соответствие пароля с заданным хэшем. Этот хэш может быть создан с помощью password_hash () или обычный crypt() хэш.

  • password-пользовательский пароль.
  • hash — хэш, созданныйфункцией password_hash() [7].

Возвращает TRUE, если пароль и хэш соответствуют или в противном случае FALSE.


Код и вывод результата

<?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);

Вывод результата

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)
  }
}

Также на сайте 3v4l.org [9] можно посмотреть VLD опкоды и сравнителную производительность на различных версиях PHP. Вот например производительность кода с статьи.

Version System time User time Max. memory usage
5.5.0alpha1 0,018 s 0,267 s 12,152 MiB
5.5.0alpha2 0,018 s 0,267 s 12,148 MiB
5.5.0alpha3 0,015 s 0,271 s 12,148 MiB
5.5.0alpha4 0,019 s 0,268 s 12,164 MiB
5.5.0alpha5 0,014 s 0,270 s 12,195 MiB
5.5.0alpha6 0,016 s 0,304 s 12,219 MiB
5.5.0beta1 0,017 s 0,270 s 12,270 MiB
5.5.0beta2 0,027 s 0,294 s 12,270 MiB
5.5.0beta3 0,022 s 0,265 s 12,656 MiB
5.5.0beta4 0,016 s 0,299 s 12,656 MiB

К сожалению финального 5.5.0 релиза пока ещё в списке нет.

Возможные будущие обновления
Установка алгоритма по умолчанию в INI — В настоящее время алгоритм по умолчанию определяется константой, которая может быть обновлена только с исходным кодом. В настоящее время имеется только один алгоритм. В будущем алгоритм по умолчанию можно будет задать в INI.
В будущих версиях PHP необходимо увеличить алгоритмическую стоимость вычисления пароля по умолчанию(BCrypt), чтобы обеспечить по умолчанию более эффективную защиту от повышения производительности оборудования. Это позволит для функции password_hash (), оставаться эффективной с течением времени, с усовершенствованием технического оснащения.

Будущие Опасения
С природой криптографии, будущая совместимость является предметом серьезного беспокойства. Для того, чтобы быть в безопасности, эти функции должны будут адаптироваться к меняющимся требованиям в будущем.

Ссылки:
Документация по [5]
Request for Comments: Adding simple password hashing API — Anthony Ferrara [10]
Бета версия нового сайта PHP.net [11]

P.S орфографические ошибки и ошибки перевода пишите в лс

Автор: Chameleoh

Источник [12]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/php-2/37110

Ссылки в тексте:

[1] на официальном сайте: http://php.net/archive/2013.php#id2013-06-20-1

[2] «Переведенное на русский»: http://www.opennet.ru/opennews/art.shtml?num=37239

[3] «Coroutines в PHP и работа с неблокирующими функциями»: http://habrahabr.ru/post/164173/

[4] «В PHP 5.5 возможно появится Finally» : http://habrahabr.ru/post/149314/

[5] "API хэширования паролей": http://ua1.php.net/manual/ru/book.password.php

[6] CRYPT_BLOWFIS: http://ua1.php.net/manual/ru/function.crypt.php

[7] password_hash(): http://ua1.php.net/manual/ru/function.password-hash.php

[8] алгоритма пароля: http://ua1.php.net/manual/ru/password.constants.php

[9] 3v4l.org: http://3v4l.org/

[10] Request for Comments: Adding simple password hashing API — Anthony Ferrara: https://wiki.php.net/rfc/password_hash

[11] Бета версия нового сайта PHP.net : http://www.php.net/?beta=1

[12] Источник: http://habrahabr.ru/post/184220/