Как обновить схему хранения паролей (изменить хешинговый алгоритм)
Мне было предложено внедрить некоторые изменения/обновления на сайт интрасети; сделайте это "будущим доказательством", как они его называют.
Мы обнаружили, что пароли хэшируются с использованием алгоритма MD5. (система существует с 2001 года, поэтому она была адекватной вовремя).
Теперь мы хотели бы обновить алгоритм хеширования до более сильного (BCrypt-hash или SHA-256).
Мы, очевидно, не знаем пароли открытого текста, и создание нового пароля для пользовательской базы не является опцией *).
Итак, мой вопрос:
Каков приемлемый способ изменения алгоритма хеширования без доступа к открытым текстам?
Лучшим решением было бы решение, полностью "за кулисами".
<суб > *) мы попытались; пытались убедить их, мы использовали аргумент "возраст пароля", пытались подкупить их кофе, пытались подкупить их пирогом и т.д. и т.д. Но это не вариант.
Суб >
Обновление
Я надеялся на какое-то автоматическое решение для решения проблемы, но, видимо, нет других вариантов, кроме как "ждать, пока пользователь войдет в систему, а затем конвертирует".
Хорошо, по крайней мере теперь я теперь не имею другого доступного решения.
Ответы
Ответ 1
Сначала добавьте поле в БД, чтобы определить, использует ли пароль MD5 или новый алгоритм.
Для всех паролей, все еще использующих MD5:
- В процессе входа в систему, где вы проверяете введенный пользователем пароль: временно сохраняйте пароль пользователя в памяти (здесь нет проблемы безопасности, как это уже есть в памяти) и выполняйте обычный хэш MD5 и сравнивайте его с хранимый хэш;
- Если был задан правильный пароль (соответствует существующему хешу), запустите временно сохраненный пароль с помощью нового алгоритма, сохраните это значение, обновите новое поле, чтобы определить, что этот пароль был обновлен до нового алгоритма.
(Конечно, вы бы просто использовали новый алгоритм для новых пользователей/новых паролей.)
Ответ 2
Я не совсем уверен в этом, так как я не специалист по криптографии. Пожалуйста, поправьте меня, если я ошибаюсь в какой-то момент!
Думаю, что у Dave P. есть лучший вариант.
... но. Существует автоматическое решение - хэш стареет хэши сами. То есть, возьмите текущие хэши и повторите их с помощью более сильного алгоритма. Обратите внимание, что, насколько я понимаю, вы не получаете никакой дополнительной безопасности от хэш-длины здесь, только добавленная криптографическая сложность нового алгоритма.
Проблема заключается, конечно, в том, что проверка пароля будет проходить через оба хэша. И вам придется сделать то же самое для нового пароля evey. Который, ну, довольно глупый. Если вы не захотите использовать подобную схему, например, Дэйв П. объяснил, что в конце концов вернется обратно к одномашинным паролям с новым алгоритмом хеширования... в этом случае, зачем вообще это беспокоиться? (Разумеется, вы можете использовать его в flashy "Улучшенная безопасность для всех паролей, применяемых немедленно!" - путь при представлении к корпоративным костюмам с относительно прямым лицом...)
Тем не менее, это опция, которая может быть немедленно применена ко всем текущим паролям без какой-либо постепенной фазы миграции.
Но мальчик, о мальчик, кто-то будет смеяться над этим кодом позже!:)
Ответ 3
Добавить passwordChange поле datetime в базу данных.
Весь пароль, установленный до дня X, проверьте с помощью MD5
Все пароли, установленные после дня X, проверяют с помощью BCrypt или что-то еще.
Ответ 4
Вы можете сохранить либо в самом хэш-поле (например, "MD5: d41d8cd98f00b204e9800998ecf8427e" ), либо в другом столбце, какой алгоритм использовался для создания этого хеша. Затем вам нужно будет изменить процесс входа в систему, чтобы использовать правильный алгоритм при проверке пароля. Естественно, любые новые пароли будут хешированы с использованием нового алгоритма. Надеемся, что пароли в конечном итоге истекают, и со временем все хеши MD5 будут отменены.
Ответ 5
Так как вы не знаете пароль открытого текста, возможно, вам нужно создать поле, которое указывает версию для включения (например, PasswordVersion bit default 0
)
В следующий раз, когда пользователь попытается войти в систему, отметьте хешированный пароль, используя текущую версию алгоритма, как и сегодня. Если он совпадает, хэш снова и обновить поле PasswordVersion
.
Надеюсь, вам не понадобится столбец PasswordVersion
больше, чем bit
. =)
Ответ 6
Вы должны изменить базу данных паролей, чтобы сохранить 3 элемента:
- Идентификатор алгоритма.
- Случайная строка солида, выбранная сервером при первом вычислении и хранении хэша пароля.
- Хэш конкатенации соли + пароль с использованием указанного алгоритма.
Конечно, их можно было просто сохранить вместе в одном текстовом поле с разделителем:
"SHA256: это-это-соль: это-это-хэш-значение"
Теперь преобразуйте существующие записи в значение с пустой солью и старый алгоритм
"MD5:: это-это-The-старо-md5-хэш-без соли"
Теперь у вас достаточно информации для проверки всех существующих паролей, но вы также можете проверить новые записи (поскольку вы знаете, какая хэш-функция была использована). Вы можете преобразовать старые записи в новый алгоритм в следующий раз, когда существующие пользователи войдут в систему, так как у вас будет доступ к этому паролю в течение этого процесса:
- Если ваша база данных указывает, что использует старый алгоритм без соли, сначала проверьте пароль по-старому, указав, что совпадение пароля MD5 совпадает. Если нет, отклоните логин.
- Если пароль был проверен, попросите сервер выбрать случайную строку солярия, вычислить хэш SHA256 с солью + пароль и заменить запись в таблице паролей новой, специфицируя новый алгоритм, соль и хеш.
- Когда пользователь войдет в систему снова, вы увидите, что они используют новый алгоритм, поэтому вычислите хэш с паролем salt + и убедитесь, что он соответствует сохраненному хешу.
В конце концов, после того, как эта система была запущена в течение подходящего времени, вы можете отключить учетные записи, которые не были преобразованы (при желании).
Добавление строки случайной соли, уникальной для каждой записи, делает эту схему гораздо более устойчивой к атакам словаря с использованием таблиц радуги.
Ответ 7
Лучший ответ от настоящего эксперта по криптографии https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016#legacy-hashes
Этот пост также помогает объяснить, какое хеширование следует использовать. Это все еще актуально, даже если это говорит 2016. Если сомневаетесь, используйте bcrypt.
Добавьте столбец в таблицу учетных записей пользователей, который называется legacy_password (или эквивалентный). Это просто логическое
Рассчитайте новый более сильный хеш существующих хешей паролей и сохраните их в базе данных.
Измените свой код аутентификации для обработки устаревшего флага.
Когда пользователь пытается войти в систему, сначала проверьте, установлен ли флаг legacy_password. Если это так, сначала предварительно хешируйте свой пароль с помощью старого алгоритма хеширования паролей, а затем используйте это предварительно хешированное значение вместо их пароля. После этого (md5) пересчитайте новый хеш и сохраните новый хеш в базе данных, отключив в процессе флаг legacy_password.