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

в 21:15, , рубрики: api, php, php 5.5, переводы, Песочница, метки: ,

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

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

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

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

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

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

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


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

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


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

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

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


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

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

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


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

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

Возвращает 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 можно посмотреть 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 (), оставаться эффективной с течением времени, с усовершенствованием технического оснащения.

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

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

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

Автор: Chameleoh

Источник

Поделиться

* - обязательные к заполнению поля