Повторное хеширование существующих паролей, хешированных с помощью устаревшей функции

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

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

Это действительно безопасно? Насколько я прочитал, каждый хэш должен увеличивать количество энтропии, и я на 90% уверен, что это так, но есть ли какие-либо проблемы при этом, о которых мне нужно знать? Я также предполагаю, что в цепочках хеширования это самая сильная хеш-функция, которая определяет «базовый» уровень безопасности, но я подумал, что дважды проверю, нет ли каких-либо странных математических причуд с хешированием «небезопасного» хеша. . Я уверен, что нет, но из-за характера проблемы я бы предпочел задать глупый вопрос, чем делать какие-либо неправильные предположения, поскольку технический аспект хеш-функций - это не то, что я действительно изучал.

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

2
0
236
1

Ответы 1

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

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

  1. Сделайте старую соль постоянной в базе данных, вам понадобится oldSalt для проверки двойного хэша.
  2. Вычислите двойной хеш и сохраните его в базе данных newHash = newSafeHashFunction(oldHash, newSalt). В настоящее время безопасными хеш-функциями являются BCrypt, SCrypt, Argon2 и PBKDF2. Сгенерируйте новую соль, удовлетворяющую требованиям новой функции хеширования пароля.
  3. После следующего успешного входа в систему двойной хеш следует заменить на чисто новый алгоритм newSafeHashFunction(password, newSalt).

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

if (checkIfDoubleHash(storedHash))
  correctPassword = newSafeHashFunction(oldUnsafeHashFunction(password, oldSalt), storedHash)
else
  correctPassword = newSafeHashFunction(password, storedHash)

➽ Обратите внимание на функцию checkIfDoubleHash(), она важна и часто встречается при двойном хешировании. Если мы обычно принимаем newSafeHashFunction(password, storedHash), и злоумышленник может получить старую резервную копию или имеет значения из более ранней SQL-инъекции, он может использовать старые хэши непосредственно в качестве пароля.

Реализация checkIfDoubleHash() может быть такой же простой, как проверка на старую соль, или может быть проверена на будущее, пометив хеш как двойной хеш. Большинство фреймворков уже предлагают функцию password_hash(), которая добавляет такую ​​«метку», чтобы при необходимости можно было переключиться на более новые алгоритмы.

$2y$10$nOUIs5kJ7naTuTFkBy1veuK0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
 |
 hash-algorithm-descriptor = 2y = BCrypt

Это часто принятый формат, используемый функцией Unix крипта (). Ничто не мешает вам использовать собственный дескриптор для двойных хешей. Конечно, отметку можно также сохранить в отдельном поле базы данных.

Другие вопросы по теме