Многое было сказано в другом ответе или комментариях.
По сути, вы не можете просто перейти от значения хеширования к другому значению хеширования, соответствующему исходному значению. Хеш-функция — это односторонняя функция.
Но не бойтесь, есть надежда! Вот подход, который позволит вам:
- Добавить новый алгоритм хеширования пароля
- Избегайте сброса пароля всех ваших пользователей
- Обработка устаревшего алгоритма хеширования паролей
- Защитите устаревший пароль с помощью нового алгоритма хеширования прямо сейчас
Выбор хэш-функции
Это важно. Пожалуйста, прочитайте внимательно.
Для хранения паролей вы не должны не использовать какие-либо (криптографические) функции хэширования, такие как SHA1, SHA2 или даже SHA3 (Keccak). Основная причина в том, что они быстрые. Слишком быстро. Это не то, к чему вы должны стремиться с хешированием паролей. Дополнительная информация.
Кроме того, они не справляются с солением, а это значит, что вам придется делать это вручную, что означает, что у вас больше шансов все испортить.
Для хранения паролей вам нужна функция хеширования паролей, созданная специально для этой цели. У вас есть несколько известных функций: PBKDF2, BCrypt, SCrypt или Argon2.
Эти функции могут обрабатывать соль и работают медленно (и производительность настраивается параметрами).
Теперь, поскольку вы используете PHP, это еще проще для вас. Функция password_hash() дает вам хорошее и работающее право BCrypt на летучая мышь. Используй это!
Он даже поддерживает Argon2, если вы используете PHP 7.2+. Но пока придерживайтесь BCrypt. Это проще и проверено в бою.
Основная проблема, с которой вы столкнетесь при работе с BCrypt, — это настройка его параметра: значение cost. Это напрямую влияет на время, необходимое для вычисления одного хэша.
В основном, это зависит от вашего сервера. Таким образом, вам нужно будет провести здесь некоторый тест, начиная со стоимости по умолчанию 10 и увеличивая ее до тех пор, пока для вычисления хэша не потребуется от 700 мс до 1 с.
Я сделал этот удобный скрипт PHP несколько раз назад, чтобы помочь мне в этой задаче. Я также сделал один для для Argon2, но, как видите, он сложнее.
Кроме того, никогда не давайте свою собственную соль. Позвольте функции сделать это за вас (даже если вы думаете, что можете добиться большего).
Реализовать новый алгоритм хеширования паролей
Как сказано в некоторых комментариях, лучший подход — добавить новый логический столбец legacy_pwd, инициализированный значением true.
EDIT: не забудьте, конечно, обновить определение таблицы относительно размера столбца. Дайджест SHA1 имеет размер 40 шестнадцатеричных символов (160 бит), тогда как дайджест BCrypt имеет размер 60 символов.
Кроме того, чтобы прямо сейчас защитить ваш существующий пароль клиента, я предлагаю вам применить новую функцию хеширования (BCrypt) к столбцу password.
Когда пользователь пытается войти со своим именем пользователя/паролем, вы сначала проверяете файл legacy_pwd.
Если legacy_pwd верно, возьмите bcrypt(sha1("plain_text_pwd")) и сравните его с одним хранилищем в БД. Если он совпадает, сохраните bcrypt("plain_text_pwd"), установите для legacy_pwd значение false и войдите в систему.
Если legacy_pwd ложно, просто возьмите bcrypt("plain_text_pwd") и сравните его с одним хранилищем в БД. Если он совпадает, войдите в систему.
Последующее наблюдение и чистка
Регулярно вам нужно будет проверять, не осталось ли в legacy_pwd какого-либо значения true. Если нет (все пользователи мигрировали), вы можете удалить столбец и удалить код, обрабатывающий устаревший пароль.
person
Indigo
schedule
05.04.2019
needs_rehash. Если для этого установлено значение true, когда пользователь входит в систему, то сверьтесь с текущим хэшем sha1, перефразируйте пароль с помощью password_hash() и установите для столбцаneeds_rehashзначение false. - person Magnus Eriksson   schedule 05.04.2019