Как обновить схему хранения паролей (изменить алгоритм хеширования) - PullRequest
25 голосов
/ 07 октября 2009

Меня попросили внести некоторые изменения / обновления в интранет-сайт; сделайте это «будущим», как они это называют.

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

Мы, очевидно, не знаем незашифрованные пароли, и создание нового пароля для пользовательской базы не вариант *) .

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

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

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

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

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

Ответы [ 7 ]

28 голосов
/ 07 октября 2009

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

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

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

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

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

6 голосов
/ 13 октября 2009

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

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

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

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

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

Но, о, боже, кто-то посмеется над этим кодом позже! :)

3 голосов
/ 08 октября 2009

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

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

Конечно, их можно просто хранить вместе в одном текстовом поле с разделителем:

"SHA256: это-это-соль: это-это-хэш-значение"

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

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

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

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

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

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

3 голосов
/ 07 октября 2009

Поскольку вы не знаете незашифрованный пароль, возможно, вам следует создать поле, в котором указана версия записи (например, PasswordVersion bit default 0)

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

Надеюсь, вам не понадобится столбец PasswordVersion больше bit. =)

3 голосов
/ 07 октября 2009

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

3 голосов
/ 07 октября 2009

Добавить поле dateChange datetime в базу данных.

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

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

0 голосов
/ 26 мая 2019

Лучший ответ от настоящего эксперта по криптографии https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016#legacy-hashes

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

Добавьте столбец в таблицу учетных записей пользователей, который называется legacy_password (или эквивалентный). Это просто логическое значение

Рассчитать новый более сильный хэш существующих хэшей паролей и сохранить их в базе данных.

Измените код проверки подлинности для обработки устаревшего флага.

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

...