hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hello" + "QxLUF1bgIAdeQX") = 9e209040c863f84a31e719795b2577523954739fe5ed3b58a75cff2127075ed1
hash("hello" + "bv5PehSMfV11Cd") = d1d3ec2e6f20fd420d50e2642992841d8338a314b8ea157c9e18477aaef226ab
hash("hello" + "YYLmfY6IehjZMQ") = a49670c3c18b9e079b9cfaf51634f563dc8ae3070db2c4a8544305df1b60f007
Радужные таблицы и таблицы поиска работают только потому, что каждый пароль хешируется совершенно одинаковым способом.
Если два пользователя имеют один и тот же пароль, у них будет совпадать и хеш-код пароля. Мы можем предотвратить эти атаки, внеся случайную составляющую в каждый хеш-код; таким образом, когда одинаковый пароль хешируется дважды, хеш-коды получаются разные.
Мы можем внести случайную составляющую в хеш-коды, добавив в конец или в начало пароля случайную строку, называемую «соль», перед операцией хеширования. При этом, как показано в примере выше, всякий раз получаются совершенно разные строки из одного и того же хеш-кода пароля.
Чтобы проверить, корректен ли пароль, нам нужна соль, поэтому обычно ее сохраняют в базе данных пользовательских аккаунтов вместе с хеш-кодом, или как часть самой строки хеш-кода.
Соль не обязательно держать в секрете. Просто при использовании случайной величины для построения хеш-кода таблицы поиска, обратные таблицы поиска и радужные таблицы становятся неэффективными. Злоумышленник не узнает заранее, какая будет соль, поэтому он не может предварительно вычислить таблицу поиска или радужную таблицу.
Если пароль каждого пользователя хешируется с помощью разной соли, атака с использованием обратной таблицы поиска также не будет работать.
В следующей секции мы рассмотрим распространенные ошибки при реализации соли.
НЕВЕРНЫЙ способ: короткая соль и повторное использование соли
Эта секция охватывает другое распространенное заблуждение насчет хеширования паролей: дурацкие комбинации хеш-алгоритмов. Очень легко увлечься и попытаться комбинировать разные хеш-функции, надеясь, что результат будет более надежным.
Хотя на практике пользы от этого мало. Все, к чему эти действия приводят – это появление проблем совместимости, а иногда они могут сделать хеш-коды даже менее надежными. Никогда не пытайтесь изобрести свой собственный алгоритм шифрования, всегда используйте стандарт, который был разработан экспертами.
Некоторые могут поспорить, что использование нескольких хеш-функций делает процесс вычисления хеш-кодов более медленным, поэтому дешифрование становится медленнее, однако, как мы увидим позже, существует более разумный способ сделать процесс взлома более медленным.
Ниже приведены некоторые примеры чокнутых хеш-функций, которые я когда-либо встречал на форумах в Интернете.
Радужные таблицы и таблицы поиска работают только потому, что каждый пароль хешируется совершенно одинаковым способом. Если два пользователя имеют один и тот же пароль, у них будет совпадать и хеш-код пароля.
Мы можем предотвратить эти атаки, внеся случайную составляющую в каждый хеш-код; таким образом, когда одинаковый пароль хешируется дважды, хеш-коды получаются разные.
Мы можем внести случайную составляющую в хеш-коды, добавив в конец или в начало пароля случайную строку, называемую «соль», перед операцией хеширования. При этом, как показано в примере выше, всякий раз получаются совершенно разные строки из одного и того же хеш-кода пароля.
Чтобы проверить, корректен ли пароль, нам нужна соль, поэтому обычно ее сохраняют в базе данных пользовательских аккаунтов вместе с хеш-кодом, или как часть самой строки хеш-кода.
Соль не обязательно держать в секрете. Просто при использовании случайной величины для построения хеш-кода таблицы поиска, обратные таблицы поиска и радужные таблицы становятся неэффективными. Злоумышленник не узнает заранее, какая будет соль, поэтому он не может предварительно вычислить таблицу поиска или радужную таблицу.
Если пароль каждого пользователя хешируется с помощью разной соли, атака с использованием обратной таблицы поиска также не будет работать.
В следующей секции мы рассмотрим распространенные ошибки при реализации соли.
НЕВЕРНЫЙ способ: короткая соль и повторное использование соли
Эта секция охватывает другое распространенное заблуждение насчет хеширования паролей: дурацкие комбинации хеш-алгоритмов. Очень легко увлечься и попытаться комбинировать разные хеш-функции, надеясь, что результат будет более надежным.
Хотя на практике пользы от этого мало. Все, к чему эти действия приводят – это появление проблем совместимости, а иногда они могут сделать хеш-коды даже менее надежными. Никогда не пытайтесь изобрести свой собственный алгоритм шифрования, всегда используйте стандарт, который был разработан экспертами.
Некоторые могут поспорить, что использование нескольких хеш-функций делает процесс вычисления хеш-кодов более медленным, поэтому дешифрование становится медленнее, однако, как мы увидим позже, существует более разумный способ сделать процесс взлома более медленным.
Ниже приведены некоторые примеры чокнутых хеш-функций, которые я когда-либо встречал на форумах в Интернете:
md5(sha1(пароль))
md5(md5(соль) + md5(пароль))
sha1(sha1(пароль))
sha1(str_rot13(пароль + соль))
md5(sha1(md5(md5(пароль) + sha1(пароль)) + md5(пароль)))
Не используйте ни одну из них.
Примечание: этот раздел оказался противоречивым. На мою электронную почту пришло много писем, в которых утверждалось, что замудренные хеш-функции – это хорошая вещь, потому что лучше, если злоумышленник не знает, какая хеш-функция используется.
Тогда менее вероятно наличие у злоумышленника предварительно вычисленных радужных таблиц для мудреной хеш-функции, и вычисление хеш-функции занимает больше времени.
Злоумышленник не может атаковать хеш-код, когда он не знает алгоритм, но учитывая принцип Керкгоффса, взломщик обычно обладает доступом к исходному коду (особенно если это приложение бесплатное или с открытым исходным кодом), и ему известны несколько пар пароль/хеш-код из целевой системы, поэтому не составляет никакого труда выполнить реверсивное программирование алгоритма.
Вычисление мудреных хеш-функций действительно занимает больше времени, но только с небольшим константным коэффициентом. Лучше использовать итеративный алгоритм, спроектированный так, чтобы его было очень сложно распараллелить (такие алгоритмы обсуждаются ниже). А, добавление соли в хеш-код, выполненное должным образом, решает проблем радужных таблиц.
Если вы действительно хотите использовать стандартизованную «чокнутую» хеш-функцию, например, HMAC, тогда нет проблем. Но если причина для этого – сделать вычисление хеш-кода медленнее, сначала прочитайте секцию ниже о растяжении ключа.
Сравните эти незначительные преимущества с риском случайного внедрения совершенно ненадежной хеш-функции и проблемами несовместимости, создаваемые мудреными хеш-функциями. Без сомнения, лучше всего использовать стандартные и хорошо протестированные алгоритмы.