Как обновить схему хранения паролей (изменить алгоритм хэширования)

меня попросили реализовать некоторые изменения / обновления для интранет-сайта; сделайте его "будущим доказательством", как они его называют.

мы обнаружили, что пароли хэшируются с помощью алгоритма MD5. (система существует с 2001 года, поэтому она была адекватной в то время).
Теперь мы хотели бы обновить алгоритм хеширования до более сильного (BCrypt-hash или SHA-256).

мы, очевидно, не знаем открытого текста-пароли и создание нового пароля для userbase является не вариант*).

Итак, мой вопрос:

каков принятый способ изменения алгоритма хэширования без доступа к паролям открытого текста?
Лучшим решением было бы решение, которое полностью находится "за кулисами".

* ) мы пытались; пытались убедить их, мы использовали аргумент "возраст пароля", пытались подкупить их кофе, пытались подкупить их тортом и т. д. так далее. Но это не вариант.

обновление
Я надеялся на какое-то автоматическое решение для решения проблемы, но, по-видимому, нет других вариантов, кроме как "дождаться входа пользователя, а затем преобразовать".

ну, по крайней мере, теперь я теперь нет другого решения.

6 ответов


Сначала добавьте поле в БД, чтобы определить, использует ли пароль MD5 или новый алгоритм.

для всех паролей, все еще использующих MD5:

-- в процессе входа в систему, где вы проверяете введенный пароль пользователя: временно сохраните представленный пароль пользователя в памяти (здесь нет проблемы безопасности, так как он уже где-то в памяти) и сделайте обычный хэш MD5 и сравните с сохраненным хэшем;

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

(конечно, вы бы просто использовали новый алгоритм для любых новых пользователей / новых паролей.)


Я не совсем уверен в этом варианте, так как я не эксперт по криптографии. Пожалуйста, поправьте меня, если я ошибаюсь в какой-то момент!

Я думаю, что Дэйв был явно лучший вариант.

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

проблема, конечно, в том, что проверка пароля должна была бы пройти и хэши. И вам придется сделать то же самое для нового пароля evey. Что, ну, в значительной степени глупо. Если вы не хотите использовать аналогичную схему, как объяснил Дэйв П., чтобы в конечном итоге вернуться к однохешевым паролям с новым алгоритмом хэширования... в таком случае, зачем вообще беспокоиться об этом? (Дарованный, вы можете использовать его в кричащей " улучшенной безопасности для всех паролей, применяемых немедленно!- ...способ на презентации корпоративных костюмов, с относительно прямым лицом...)

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

но мальчик, О мальчик, кто-то будет хорошо смеяться, глядя на этот код позже! :)


добавить поле типа datetime об изменении пароля к базе данных.

все пароли, установленные до дня X, проверьте с помощью MD5

все пароли, установленные после дня X, проверьте с помощью BCrypt или что-то еще.


вы можете хранить либо в самом хэш-поле (например, "MD5:d41d8cd98f00b204e9800998ecf8427e"), либо в другом столбце, алгоритм которого использовался для создания этого хэша. Затем вам нужно будет изменить процесс входа в систему, чтобы использовать правильный алгоритм при проверке пароля. Естественно, любые новые пароли будут хэшироваться с использованием нового алгоритма. Надеюсь, пароли в конце концов истекает, и со временем все хеши MD5 будут постепенно отменены.


поскольку вы не знаете пароль открытого текста, возможно, вам следует создать поле, которое указывает версию encription (например,PasswordVersion bit default 0)

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


вы должны изменить базу данных паролей для хранения 3 элементов:

  1. идентификатор алгоритма.
  2. случайная строка соли, выбранная сервером при первом вычислении и сохранении хэша пароля.
  3. хэш конкатенации salt + password с использованием указанного алгоритма.

конечно, они могут быть сохранены вместе в одном текстовом поле с разделителем:

"SHA256: this-is-salt: this-is-hash-value"

теперь преобразуйте существующие записи в значение с пустой солью и старым алгоритмом

"MD5 с::это---старый-MD5-хеш-без-соли"

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

  1. Если ваша база данных указывает, что они используют старый алгоритм без соли, сначала проверить пароль по старинке, проверяя, что MD5-хэш пароля. Если нет, отклоните логин.
  2. Если пароль был проверен, попросите сервер выбрать случайную строку соли, вычислить хэш SHA256 пароля salt+и заменить запись таблицы паролей новой спецификацией новый алгоритм, соль и хэш.
  3. когда пользователь снова войдет в систему, вы увидите, что они используют новый алгоритм, поэтому вычислите хэш пароля salt+и убедитесь, что он соответствует сохраненному хэшу.

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

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