Плохая идея — создавать собственный хэш пароля.
Создание криптографических функций по-прежнему представляет собой процесс проб и ошибок. Конечно, со временем мы наткнулись на некоторые вещи, которые являются хорошей идеей или даже обязательными. И мы, конечно, узнали много вещей, которые не работай. Но мы не знаем, как сделать вещи, которые полностью безопасны. Очень тонкая небольшая ошибка может привести к катастрофическому сбою криптографической конструкции. И здесь много возможностей для таких ошибок. Я назову некоторые позже.
Лучшее, что мы можем сделать прямо сейчас, это чтобы люди, имеющие опыт в этом, создали криптовалюту, а затем все попытались взломать эту криптовалюту. Если все стараются и долго не добиваются успеха, то, вероятно, у нас есть что-то достаточно хорошее. Мы до сих пор не можем доказать отсутствие проблем, но если тысячи криптоаналитиков не смогли, то, надеюсь, и следующая тысяча тоже не сможет.
Но даже это время от времени дает сбой. Иногда по прошествии лет, а то и десятилетий в чем-то, что веками изучали умнейшие люди, обнаруживается острая проблема. Вот почему MD5 больше не считается нормальным, а RC4 считается проблематичным. Или ландшафт меняется, что приводит, например. к необходимости использования солей в хэшах паролей и преднамеренно медленных хэш-функциях.
Используя самые известные современные криптографические алгоритмы, мы можем использовать этот коллективный опыт и, возможно, избежать повторения прошлых ошибок. Могут быть обнаружены новые ошибки, но с этим ничего не поделаешь. Однако тот, кто создает свои собственные криптографические функции, скорее всего, повторит некоторые из этих ошибок или создаст совершенно новые.
Я знаю, я знаю, это забавно создавать такие штуки самостоятельно. И приятно создавать что-то, что кажется безопасным. Stack Exchange завален вопросами о пользовательском шифровании и (особенно) хэшах паролей. Проблема в том, что легко построить то, что сам не сможешь сломать. Но это не значит, что другие не могут.Эта пословица древняя и встречается достаточно часто, поэтому теперь известна как закон Шнайера.
Что может пойти не так?
Таким образом, могут быть проблемы с самим ядром криптоалгоритма. Это то, что сломало MD5 и RC4.
Или алгоритм может быть совершенно исправен, но реализация может быть нарушена. Это может быть простая ошибка, а может быть что-то более тонкое, например, атака по сторонним каналам (которых иногда на удивление сложно избежать).
Но также возможно (даже легко) использование безопасных криптографических примитивов с безошибочной реализацией неправильно, что делает систему небезопасной. Например, правильно использовать шифрование и цифровые подписи, но делать наивные предположения во время коммуникационного рукопожатия (у SSL были свои проблемы с этим). Другим известным примером является AES-ECB, который использует превосходный AES таким образом, что может привести к утечке важной информации.
В вашей хеш-функции?
Ваша собственная функция хеширования паролей также становится жертвой чего-то вроде этого здесь:
повторить 100_000:
хэш = sha512 (хеш)
SHA-512 прекрасно работает (насколько нам известно). Использование его таким образом осуждается.
SHA-512 генерирует «неотличимый от случайного» 512-битный вывод для каждого ввода. Он может генерировать один и тот же результат для двух разных входов, это называется коллизией. Проблема в том, что N-битные хеш-функции на N-битных входных данных обычно не работают. биективный. Это означает, что при передаче вывода SHA-512 самому себе некоторые из возможных 512-битных значений будут конфликтовать с другими, создавая тот же результат. К необходимость, это также означает, что некоторые другие хеш-значения вообще не могут быть сгенерированы.
Давайте посмотрим, как это работает для SHA-512, усеченного до 4 бит. В частности, мы берем первый байт из вывода и обнуляем старшие 4 бита в этом байте. Полученный одиночный байт используется в качестве входных данных для следующего раунда. Различные способы выбора битов дают разные результаты, но принцип один и тот же.
Пробуя все 16 возможных входных данных в течение нескольких раундов, мы получаем следующие цепочки:
в 1. 2. 3. 4. 5. 6. 7.
00 -> 08 -> 06 -> 08 -> 06 -> 08 -> 06 -> 08
06 -> 08/
07 -> 06 -> 08 -> 06 -> 08 -> 06 -> 08 -> 06
08 -> 06/
03 -> 04 -> 05\
13 -> 15 -> 05 -> 09 -> 02 -> 10 -> 14 -> 14
04 -> 05 -> 09 -> 02 -> 10 -> 14 -> 14/
15 -> 05 -> 09 -> 02 -> 10 -> 14/
05 -> 09 -> 02 -> 10 -> 14 -> 14
01 -> 11 -> 02 -> 10 -> 14/
09 -> 02 -> 10 -> 14 -> 14
11 -> 02 -> 10 -> 14/
02 -> 10 -> 14 -> 14
12 -> 10//
10 -> 14 -> 14
14 -> 14/
Всего после 6 раундов 16 возможных выходов сократились до 3. Тот же эффект можно увидеть и для больших усечений. Я выполнил несколько симуляций для SHA-512, усеченного до первого 1 байта (2 ), 2 байта (2 ) и 3 байта (2 ²):
байт: 1 2 3
поле ввода: 256 65536 16777216
сошлись к значениям M: 13 330 2765
после N раундов: 31 518 7114
Вы можете видеть, что эффект конвергенции присутствует во всех трех сценариях. Что касается неразрезанного SHA-512, мой компьютер недостаточно быстр, чтобы вычислить это, я не смог найти никакой информации о силе и определенности эффекта, и я недостаточно умен, чтобы построить доказательство (если доказательство даже возможно). Но есть вероятность, что вы увидите эффект и в полном SHA-512. Мой инстинкт подозревает, что это уменьшает хеш-пространство на его квадратный корень (уменьшая вдвое длину бита), но я могу сильно ошибаться [обновление: см. ссылки в комментариях: один, два, три]. 100 тысяч патронов, вероятно, тоже ограничивают урон.
Теперь, действительно ли это вредит вашему хэшу? Возможно нет. Но это является слабость, которую стараются избегать реальные хеш-функции паролей (например, регулярно смешивая пароль и соль).
Я думаю, что это отличный пример изощренных ловушек в криптографическом дизайне. Так легко пропустить что-то подобное. Вот почему я рекомендую использовать проверенный в бою алгоритм. Они лучше всего, что вы или я можем придумать.
Другие ответы уже дают некоторые рекомендации по использованию хэшей; Хорошо: pbkdf2, bcrypt. Лучше: аргон2, скрипт. Я слышал, что Balloon — вещь, но я ничего о ней не знаю, поэтому у меня нет о ней мнения.