Password_verify работает в PHP 7.4, но не работает в PHP 8.2

У меня есть два док-контейнера, в одном PHP 8.2.3, в другом PHP 7.4.30.

Кроме того, у меня есть база данных с существующими хэшами паролей (которые были изначально созданы фреймворком Yii2 с использованием пароля password_hash в неизвестной среде).

Я сделал test.php, где вывел две вещи:

var_dump(password_get_info('$2a$07$6c2eb62b00df224f3d20$.qzdiDRZejMnGytXWsA7Jid7RpWazDc6'))

И

var_dump(password_verify('password', '$2a$07$6c2eb62b00df224f3d20$.qzdiDRZejMnGytXWsA7Jid7RpWazDc6'))

В PHP 7.4 результаты следующие:

array(3) {
  ["algo"]=>
  NULL
  ["algoName"]=>
  string(7) "unknown"
  ["options"]=>
  array(0) {
  }
}

И

bool(true)

В то время как в PHP 8.2:

array(3) {
  ["algo"]=>
  NULL
  ["algoName"]=>
  string(7) "unknown"
  ["options"]=>
  array(0) {
  }
}

И

bool(false)

Я знаю, что могли использоваться разные алгоритмы хеширования. Но алгоритм хеширования должен быть указан (и, следовательно, идентифицирован) в самом хеше.

Кроме того, оба двигателя не знают алгоритма. Однако PHP 7.4 может проверить пароль.

Почему это происходит?

Из документов:

Обратите внимание, что password_hash() возвращает алгоритм, стоимость и соль как часть возвращаемого хэша. Поэтому вся информация, необходимая для убедитесь, что хэш включен в него. Это позволяет функции проверки проверить хэш без необходимости отдельного хранения для соли или

FWIW, кажется, это ошибка конкретно в этой версии PHP (и двух других): 3v4l.org/aJlhb

deceze 21.02.2023 11:26

Что за... о, большое спасибо. Это невероятно. Почему? Так как это минорная версия. Супер странно

Victor 21.02.2023 11:29

Вероятно, конкретно связано с этим исправлением: bugs.php.net/bug.php?id=81744

deceze 21.02.2023 11:30

Хотя я не могу найти фактическое изменение кода, связанное с этим, это единственное актуальное изменение в этих затронутых версиях: php.net/ChangeLog-8.php#8.2.3 , php.net/archive/ 2023.php#2023-02-14-3

deceze 21.02.2023 11:35
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Laravel - это мощный PHP-фреймворк, используемый для создания масштабируемых и надежных веб-приложений. Одним из преимуществ Laravel является его...
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание API-ресурса Laravel может быть непростой задачей. Она требует глубокого понимания возможностей Laravel и лучших практик, чтобы обеспечить...
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Аутсорсинг разработки PHP для индивидуальных веб-решений
Аутсорсинг разработки PHP для индивидуальных веб-решений
Услуги PHP-разработки могут быть экономически эффективным решением для компаний, которые ищут высококачественные услуги веб-разработки по доступным...
Еще один бенчмарк PHP
Еще один бенчмарк PHP
Сегодня я наткнулся на забавный пост на r/ProgrammerHumor, который заставил меня задуматься об одной вещи, которая меня всегда интересовала....
Преобразование данных с помощью красноречивых аксессоров и мутаторов в Laravel
Преобразование данных с помощью красноречивых аксессоров и мутаторов в Laravel
Laravel поставляется с мощной функцией под названием "Eloquent Accessors and Mutators".
3
4
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На вас повлияло это исправление:

Неправильно отформатированные хэши BCrypt, которые содержат $ в своей солевой части, вызовут перезапись буфера и могут ошибочно признать действительным любой пароль. [..] «PHP Hack» существует с самой первой версии собственной crypt_blowfish реализации PHP, и в комментариях или истории коммитов не дается четкого объяснения его существования. В любом случае такой хэш не является действительным хэшем BCrypt и не генерируется password_hash(), который является рекомендуемым API хеширования паролей в PHP. Хотя технически это может нарушить обратную совместимость с существующими пользователями, тот факт, что эти хэши никогда не генерируются password_hash(), не принимаются другими реализациями BCrypt и представляют возможные уязвимости безопасности в приложениях, они должны быть отклонены во всех поддерживаемых версиях PHP. https://github.com/php/php-src/security/advisories/GHSA-7fj2-8x79-rjf4

Акцент здесь делается на том факте, что ваш хеш, по-видимому, технически недействителен с самого начала и никогда не должен был существовать.

Я помню, что более ранние версии password_hash() допускали использование соли пользователем. Так что держу пари, что здесь должно быть так.

Your Common Sense 21.02.2023 14:33

Может и правда. До сих пор я узнал, что хэш был жестко запрограммирован при миграции базы данных, предполагая, что это хэш для «пароля». Но как был сгенерирован хеш - никто не знает. Хорошей новостью является то, что это только для среды разработки. Первый раз в жизни я натыкаюсь на ошибку после минорного обновления версии, прямо перед установкой нового контейнера докеров. До 14 февраля я бы не столкнулся с этим :)

Victor 21.02.2023 15:55

@YourCommonSense Как автор этого совета: Нет, password_hash никогда не мог выдать искаженный хеш, даже с добавленной пользователем солью. В этом случае также легко увидеть, что хэш не был сгенерирован password_hash из-за префикса $2a$ вместо $2y$. Хеш, вероятно, был создан путем прямого вызова crypt().

TimWolla 22.02.2023 11:47

Другие вопросы по теме