Преобразовать sha1 в bcrypt?

У меня есть приложение PHP с довольно приличной пользовательской базой. К сожалению, все эти годы он использовал sha1($password . $salt), и я действительно хочу отказаться от этого в пользу bcrypt. Я нашел несколько хороших способов получить хэш Blowfish, но я все еще не уверен в подходе к преобразованию, который мне следует использовать. Вот мои варианты:

Опция 1

Каждый раз, когда пользователь входит в систему, я проверяю, начинается ли хэш с $2. Если нет, я предполагаю, что это sha1, возьмите пароль, введенный пользователем, получите для него хэш bcrypt и замените старый хэш в базе данных.

Вариант 2

Я заменяю свой класс авторизации, чтобы сделать это:

$hash = password_hash("rasmuslerdorf", sha1($password . $salt));

Таким образом, преобразование происходит быстрее.

Но, честно говоря, мне не очень нравится ни один из вариантов. Оба предполагают, что я все еще храню устаревшую проверку в кодовой базе, от которой я хочу избавиться.

Любые предложения, которые из двух вышеперечисленных лучше с точки зрения стандартов кодирования? Или у кого-то есть лучшее решение?


person Sayak Banerjee    schedule 10.07.2013    source источник
comment
возможный дубликат Most эффективный способ изменить хэш-тип пароля (с md5 на sha1)   -  person Baba    schedule 11.07.2013
comment
вам придется сохранить НЕКОТОРЫЙ устаревший код, пока все ваши пользователи не будут преобразованы, иначе устаревшие пользователи будут заблокированы, потому что они не могут пройти проверку хэша.   -  person Marc B    schedule 11.07.2013
comment
@MarcB Вот в чем проблема, я знаю список из 20 сайтов, которые используют мое приложение. Я не знаю, кто их поддерживает, поэтому у меня нет возможности проверить, полностью ли они мигрировали.   -  person Sayak Banerjee    schedule 11.07.2013
comment
ах. так что это не один сайт со многими пользователями, это несколько сайтов/серверов с несколькими копиями вашего приложения. Я бы посоветовал вам сделать так, как сам PHP - развернуть новый хеш как функцию в новой версии, отказаться от старой версии. затем, после пары версий, вы удаляете устаревший хеш-материал, и это очень плохо для всех пользователей, все еще работающих в старой системе. Немного дополнительной работы для нескольких версий, но, по крайней мере, вы предупреждаете своих пользователей.   -  person Marc B    schedule 11.07.2013
comment
Это отличная идея! Как я могу отметить это как ответ? :)   -  person Sayak Banerjee    schedule 11.07.2013


Ответы (2)


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

Ваш вариант 1 — удобный подход, если только хэши не ужасно небезопасны (несоленый или очень слабый алгоритм). В новом PHP API паролей у вас даже будет функция password_needs_rehash(), чтобы определить, необходимо ли обновление.

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

person martinstoeckli    schedule 11.07.2013
comment
Спасибо, не знал о password_needs_rehash() - person Sayak Banerjee; 11.07.2013

Добавьте новый столбец БД, скажем, [passNeedSystemUpdate], ваше значение по умолчанию будет 1. 1 = истина или да и 0 = нет.

Обрабатывайте вход пользователя в систему как обычно, пока не дойдете до конца, затем запустите проверку, чтобы убедиться, что passNeedsSystemUpdate = 1. Если пароль нуждается в обновлении, мы берем пользовательский ввод из поля пароля и обновляем новый пароль вместе с passNeedSystemUpdate, который теперь быть 0.

ПРИМЕЧАНИЕ. В случае, если ваша БД будет скомпрометирована или была взломана, у пользователей не будет другого выбора, кроме как создать совершенно новый пароль. Вышеприведенное — всего лишь немного логики, которую можно использовать, если вы меняете текущее шифрование с sha256 на bycrypt или что-то еще.

person theIrishBloke    schedule 07.12.2016
comment
Зачем накладные расходы на добавление нового столбца (который используется только один раз и в конечном итоге устареет), когда то же самое можно сделать, просмотрев формат хэша (который также останется актуальным навсегда)? - person deceze♦; 07.12.2016