Перенос с SHA256 хешированных паролей на BCRYPT в PHP7 + MySQL - PullRequest
2 голосов
/ 16 июня 2019

У меня есть старое веб-приложение с несколькими зарегистрированными пользователями, которое использует небезопасный hash("sha256", trim($_POST["password"])) для хранения хешированного пароля в базе данных MySQL. Теперь я хочу обновить веб-приложение, чтобы использовать более защищенный BCRYPT password_hash(), однако я не хочу отправлять всем зарегистрированным пользователям электронные письма с предупреждением об изменении их пароля. Поэтому я думал о реализации BCRYPT для хэшированного пароля sha256 () следующим образом:

Для сохранения пароля я буду sha256 () хэшировать пароль пользователя:

$hashed_password = password_hash(hash("sha256", trim($_POST["password"])), PASSWORD_BCRYPT);

Затем я сохраню хешированный пароль BCRYPT в базе данных.

И чтобы проверить пароль пользователя, я бы просто сделал это:

$hashed_password = "select hashed_password from users where email = 'abc@email.com'";

if(password_verify(hash("sha256", trim($_POST["password"])), $hashed_password))
{
    echo "Welcome";
}
else
{
    echo "Wrong Password!";
}

Таким образом, я просто обновлю пароль пользователя в базе данных MYSQL путем зацикливания каждого зарегистрированного пользователя, затем извлеку хэшированный пароль sha256 () и, наконец, просто заново сохраню его после того, как он был BCRYPTed с password_hash ( ):

$new_password = password_hash($old_sha256_hashed_password, PASSWORD_BCRYPT);

$mysql->save_user_password($new_password, $user_id);

Таким образом, пользователи по-прежнему смогут войти со своим старым паролем.

Что вы думаете об этом решении?

Все еще безопасно, даже если я sha256 () хеширую пароль перед BCRYPT?

1 Ответ

1 голос
/ 17 июня 2019

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

Сделать старые хэши более безопасными:

$doubleHashToStoreInDb = password_hash($oldUnsaltedSha256HashFromDb, PASSWORD_DEFAULT);

Выполнение этого для каждой строки защитит незащищенные пароли. Обратите внимание на параметр PASSWORD_DEFAULT, он должен быть предпочтительнее, чем определенный алгоритм, потому что это будущее. И пометьте двойные хеши, чтобы вы могли различить двойные хеши и уже преобразованные хеши, посмотрите, почему .

Обработка новых регистраций пользователей:

$hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT);

Просто используйте новый алгоритм без двойного хеширования.

Проверка логинов:

if (checkIfDoubleHash($storedHash))
{
  $correctPassword = password_verify(oldPasswordHash($_POST["password"]), $storedHash);
  if ($correctPassword)
    storeConvertedHash(password_hash($_POST['password'], PASSWORD_DEFAULT));
}
else
{
  $correctPassword = password_verify($_POST['password'], $storedHash);
}

// Hashes the user password with a deprecated hashing scheme
function oldPasswordHash($password)
{
  return hash("sha256", trim($password));
}

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

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

...