Существует распространенное заблуждение, что хеширование и шифрование — это одно и то же. Они не были. Хеш необратим. Возьмем следующий пример:
$ echo -n Password123 | md5sum
42f749ade7f9e195bf475f37a44cafcb -
Передаем строку "Password123" алгоритму MD5 (algo), который выполняет математические операции и возвращает сгенерированный хеш шестнадцатеричного кодирования. Единственный способ получить одно и то же значение хеш-вывода - ввести algo в оригинал. Есть конфликты, но мы можем обсудить это позже.
Большинство алгоритмов хеширования выводят шестнадцатеричную кодированную двоичную строку фиксированной длины. Другие, как в этом примере, используют строки, закодированные в base64, в качестве выходных данных. Обратите внимание, что длина всегда одинакова:
{SHA} uNF8eZRJ8jmr8WTjyocRJPVpe7w =
{SHA} lqdu / Zr6o2dgIER8Up1 / 7lcUtgw =
{SHA} qYUOwLMlDEuukA5HCT4LR1kQzco =
{SHA} MXZBCpyWJ7TTs1w2kgGJslwNwTg =
{SHA} 2sAPLaUh9Mz0bI + XxKEg7qyABe8 =
TL; Dr.
Я не хочу слишком много говорить о шифровании (потому что эти вещи предназначены для книг), но важно уметь отличать хэш-строку от зашифрованной. Шифрование обычно заполняет строки, удовлетворяющие определенной длине, прежде чем произойдет шифрование. Он также требует ключа (или пароля) для расшифровки. Если используется шифрованный пароль, строка будет меняться в зависимости от длины ввода. Если вы видите кучу шифротекстовых паролей разной длины, вероятно, вы имеете дело с шифрованием, а не с хешированием. Пример AES-256-CBC Шифрование строки и связанного с ней обычного текста (ключ "ASDF"):
foobar | U2FsdGVkX19G+KtytNHdj6yH2AVvX26pEmtunS/PRnU= foobarfoobar | U2FsdGVkX18sPpIvN6nVh68lOUCcb3gR2fKbCCnBxog= foobarfoobarfoobar | U2FsdGVkX1/EOnUt57TCW4Rh0EdNnWX lDatuQv2xEXXeAeowW0XG/EXJUe9aSUz $ cat зашифрованные_пароли U2FsdGVkX19G KtytNHdj6yH2AVvX26pEmtunS/PRnU= U2FsdGVkX18sPpIvN6nVh68lOUCcb3gR2fKbCCnBxog= U2FsdGVkX1/EOnUt57TCW4Rh0EdNnWX lDatuQv2xEXXeAeowW0XG/EXJUe9aSUz $ for i in `cat encrypted_passwords`; do echo $i | openssl enc -base64 -d -aes-256-cbc -pass pass:asdf; эхо; Готово foobar foobarfoobar foobarfoobarfoobar
Теперь вы можете подумать: наверное, вы правы. Тем не менее, ключевые материалы должны быть доступны для системы. Это означает, что, по сути, простой текстовый главный пароль, расположенный где-то - будь то ключ RSA или пароль или файл, встроенный в базу данных, жестко закодированный в приложении или где-то в памяти. Пффф, никто не будет использовать asdf в качестве ключа для шифрования паролей своих пользователей'
Используйте ту же строку для MD5:
foobar | 3858f62230ac3c915f300c664312c63f foobarfoobar | 59faa421729e846dd800dce59943bfc0 foobarfoobarfoobar | 1352aadab322d1a033c27964be0965db
Хеш-пароль далек от совершенства, на самом деле он немного плохой, но он хуже, чем шифрование из-за того, что он пытается достичь. Пользователи выбирают абсолютный минимум требований чаще, чем НЕ, а также могут использовать его на нескольких сайтах. Многие «хаки» на самом деле являются не чем иным, как атаками повторного использования учетных данных. Если первоначальным компромиссом было использование шифрования, то единственное усилие, которое придется приложить злоумышленнику, - это найти ключ для расшифровки всех паролей. Что касается хэшей, то им нужно приложить хотя бы усилия, чтобы взломать их. При использовании с современными алгоритмами, такими как sha512crypt, bcrypt, scrypt или argon2, хеш может потребовать больших усилий для взлома.
Salt - это добавление строки к паролю перед хэшированием. Соль для каждого хэша должна быть уникальной и обычно выбирается случайным образом, поскольку основное внимание уделяется тому, чтобы одно и то же значение хэша «password» в открытом тексте было разным каждый раз. Это затрудняет жизнь взломщикам паролей, потому что для того, чтобы проверить слово «пароль» у каждого из 1000 пользователей, у каждого из которых есть уникальная соль, они должны сделать работу 1000 раз — один раз на пользователя/соль. Это также означает, что они не могут эффективно использовать предварительно скомпилированные словари или таблицы rainbow (обычно ...), потому что они требуют пользовательского на соль.
Сайты иногда облажаются этим и используют универсальную соль для всех пользователей; Это противоречит цели.
Вот хеш SHA1 с солью:
b353977827f67a4ae0318f3a9447fae1c13d9d90:b8d18ca |___________________________________________| хэш | соль | Разделитель
Открытый текст этого хэша - «пароль». Он имеет значение соли "b8d18ca" и использует API SHA1 ($salt.$pass). Это означает, что алгоритм получает открытый текст пароля, генерирует соль и добавляет его перед открытым текстом. Когда веб-сайт или приложение пытается проверить ваш пароль В будущем он будет использовать ваш открытый текстовый пароль в качестве входных данных, читать значение соли в сохраненном хэше, добавлять его перед выбранным вами паролем и сравнивать полученное значение хэша с сохраненным. Если вы не знаете, что его часть является солью, хэш будет генерировать следующий обычный текст:
b8d18capassword
Поскольку алгоритм вводит обычный текст, соль и сгенерированное значение хэша могут оставаться прозрачными для пользователя. Во время крекинга, если алгоритм солевой, нам нужно знать соль, чтобы мы могли предоставить ее при генерации открытого текста-кандидата.
При правильной реализации засолка может сделать растрескивание более длительным. Используя случайную соль, вы заставляете Cracker тратить время, пытаясь взломать несовпадающие хэши соли. Это примерно усилие, необходимое для завершения device_speed / number_of_salts, поскольку нам нужно сгенерировать кандидата для каждой соли. Если соль статическая, то математические операции одинаковые...скорость_устройства / 1. Другой способ посмотреть это:
наши GTX 980 трещины SHA1($salt.$pass) at 3576.8 мГц/с или 3.5 миллиардов кандидатов за секунду Наш хешлист содержит 1000 уникальных солей 3 500 000 000 / 1000 = 3 500 000 кандидатов за секунду
Это на три порядка медленнее, потеря 99,9%. При использовании статической соли это выглядит следующим образом:
Our GTX 980 cracks SHA1($salt.$pass) at 3576,8 MH/s или 3,5 миллиарда кандидатов за секунду Наш хешлист содержит 1 уникальный соль 3,500,000,000 / 1 = 3,500,000,000 candidates per second
Если это не имеет смысла, читайте дальше, у нас будет красивая диаграмма позже...
Еще одно распространенное улучшение по сравнению с простым «хешированием этого открытого текста» заключается в том, что «хеширование этого открытого текста, затем хеширование этого результата, затем хеширование этого результата» повторяется тысячи раз. Таким образом, взломщик пароля должен выполняться тысячи раз при попытке одного пароля-кандидата. Это называется итерацией, циклом или переменной стоимостью. Некоторые алгоритмы хеширования паролей используют жестко закодированные итерационные раунды; Другие Git. делает его настраиваемым в части самого хэша. Например, md5crypt() использует MD5, включая salt, и делает ровно 1000 циклов. sha512crypt() использует sha512, включая соль, и зацикливает настраиваемое количество раз (по умолчанию 5000).
итерация в основном влияет на стоимость вычислительного цикла алгоритма хеширования, а не на его потребление памяти или другие факторы. Эти атаки также важны, когда дизайн оптимизирован для противостояния определенным типам хэш-типов, но это слишком глупо, чтобы обсуждать здесь.
Рассмотрим несколько примеров, демонстрирующих влияние выбора алгоритма хэширования, будь то соленый, использование нескольких итераций и т.д. Допустим, злоумышленники собрали хеш-значения 1000 пользователей с какого-то зараженного сайта, которые хотят провести всего лишь одну простую атаку, тестируя каждый пароль Хеш-значение - 143 миллиона паролей-кандидатов.
Тип хэша, используемого зараженным веб-сайтом, будет иметь огромное влияние на время, необходимое для атаки злоумышленника. Вот диаграмма (относительно, примерно) сколько Для завершения атаки потребуются секунды, в зависимости от типа используемого хэша, где Стандартная видеокарта:
Ну, это бесполезно! Самые сильные хэш-типы гораздо медленнее, но быстрее. Тип просто сплющен до ничего. Давайте снова попробуем использовать логарифмическое время по оси X. Размер данных. Когда бары перемещаются слева направо, они увеличиваются на 10 в степени:
Итак, некоторые важные моменты: когда вы хотите взломать какой-то хэш пароля, один раунд проще, чем несколько раундов и без соли, чем с солью. Напротив, когда некоторые компании или веб-сайты объявляют об утечке данных, содержащих пользовательские данные, а) пароль должен быть хеширован, а не просто простой текст; б) их лучше солить, а не просто хешировать; c) Им лучше всегда использовать мощный многораундовый соленый хэш, а не только один раунд.
Прежде чем попытаться взломать заданный хэш пароля, взломщику предстоит выяснить, какой алгоритм хэширования используется для его реализации. Идентификация типов хеша обычно проста, но не всегда. Крекеры обычно делают обоснованные догадки, основываясь на подсказках, таких как длина хэша и формат. В конце концов, единственный способ убедиться, что угадывание типа хэша верно, это если хэш взломан.
Здесь и здесь представлены несколько отличных ресурсов для этой задачи, и все они показывают, как выглядят общие хэши.
В Kali Linux доступен пакет "hash-identifier" (доступен здесь), который помогает идентифицировать неизвестные типы хэшей.
Столкновение возникает, когда два разных входа приводят к одному и тому же хеш-выводу. Это плохо (видимо). Что касается паролей, это может означать, что я, возможно, не взломал ваш фактический пароль, но поскольку я нашел вход, который дает такое же значение хэша, я могу использовать простое текстовое значение, чтобы обмануть систему, чтобы она думала, что пароль является законным.
Microsoft Office использует в своей защите документов алгоритм, который на протяжении многих лет был подвержен конфликтам. Нередко обнаруживается несколько конфликтов с одним хэшем, и все эти конфликты разблокируют документ.
Как только конфликт обнаружен, алгоритм фактически нарушается. Если это произойдет один раз, то статистически, скорее всего, повторится. Единственное, что мешает нам, — это время и способность к обработке. По мере того, как алгоритмы становятся более надежными, требуется больше возможностей и времени для создания алгоритмов-кандидатов и сравнения хеш-выходных данных для их поиска. В результате дизайнеры становятся все лучше и лучше создавать алгоритмы, которые менее подвержены конфликтам.