Может кто-нибудь объяснить, как сделать хеширование паролей + соление

Я читал на SO (и на других веб-сайтах, найденных в Google после того, как я попытался немного изучить его), что правильный безопасный способ хранения паролей в базе данных - это хранить хешированное + соленое значение пароля. Вдобавок ко всему, соль должна быть разной для каждого пользователя, чтобы хакеры не могли навредить, даже если у них есть зашифрованные значения.

Я не совсем понимаю, что такое соление. Насколько я понимаю, вы хешируете пароль, затем используете другое значение, которое вы хешируете (соль), и объединяете эти два вместе, чтобы алгоритм получения исходного пароля был разным для каждого пользователя.

Итак, в основном, что мне нужно сделать, это хешировать пароль, затем использовать другой хеш для другого значения для каждого пользователя (например, имя пользователя или адрес электронной почты), а затем я могу выполнить простую математическую операцию с этими двумя значениями. чтобы получить зашифрованный пароль.

Это правильно или я просто ничего не понял про хеширование паролей + засаливание?

Простое объяснение или пример могут оказаться полезными, поскольку сайты, которые я нашел, не совсем ясно объясняют, что такое соление пароля.

Изменить: Прочитав оставленные комментарии и ответы, я понял, что не совсем понял, что такое соль, потому что мне не хватает некоторых ключевых понятий и я делал ложное предположение.

Что я хотел бы знать: как вы постоянно получаете одну и ту же соль, если она генерируется случайным образом? Если соль хранится в базе данных, как упоминали некоторые люди, тогда я вижу, как вы продолжаете получать ту же соль, но это вызывает другой вопрос: как это сделать пароли более безопасными, если кто-либо, имеющий доступ к базе данных, имеет доступ к соль? Разве они не могли бы просто добавить (известную) соль ко всем паролям, которые они пробуют, и результат был бы таким же (за исключением небольшой потери времени), чем при его отсутствии?


person Adam Smith    schedule 31.07.2011    source источник
comment
en.wikipedia.org/wiki/Salt_(cryptography)   -  person Mitch Wheat    schedule 31.07.2011
comment
en.wikipedia.org/wiki/Password_cracking   -  person Mitch Wheat    schedule 31.07.2011
comment
Я прочитал ту первую статью, когда смотрел в Google, но не мог понять, как они последовательно генерируют случайные биты (если это случайное, то при попытке аутентификации соль не будет такой же, поэтому не сработает). Это то, что я не совсем понимаю, и решил, что биты, должно быть, были сгенерированы где-то еще.   -  person Adam Smith    schedule 31.07.2011
comment
Связанный, но не прямой ответ: распространенным методом безопасного хранения паролей в наши дни является использование bcrypt en. wikipedia.org/wiki/Bcrypt, в котором хранится пароль с общедоступной солью. Безопасность заключается в том, что шифрование пароля выполняется медленно, поэтому атаки методом грубой силы требуют больше времени.   -  person Charles Ma    schedule 31.07.2011


Ответы (7)


Позвольте мне попытаться немного прояснить ситуацию на несколько упрощенном примере. (md5() используется только для примера - вам не следует не использовать его на практике.)

Соль - это просто случайная строка символов, которая добавляется к паролю перед его хешированием. Допустим, у вас есть пароль letmein, и вы его хешируете вот так ...

 echo md5('letmein')

... вы получите результат 0d107d09f5bbe40cade3de5c71e9e9b7. Если вы погуглите, вы увидите ряд страниц, сообщающих вам, что это Хеш MD5 для letmein. Соль предназначена для предотвращения подобных явлений.

Предположим, у вас есть функция randomStringGenerator(), которая генерирует случайную $x-символьную строку. Чтобы использовать его для добавления пароля, вы должны сделать что-то вроде этого:

 $password = 'letmein';
 $salt = randomStringGenerator(64); //let's pretend this is 747B517C80567D86906CD28443B992209B8EC601A74A2D18E5E80070703C5F49

 $hash = md5($password . $salt);

Затем вы выполняете md5(letmein747B517C80567D86906CD28443B992209B8EC601A74A2D18E5E80070703C5F49), который возвращает af7cbbc1eacf780e70344af1a4b16698, который нельзя "найти" так же легко, как letmein без соли.

Затем вы должны сохранить ОБЕИ хэш и соль, и когда пользователь вводит свой пароль для входа в систему, вы должны повторить описанный выше процесс и посмотреть, добавлены ли хеши, введенные пользователем с сохраненной солью, к тому же самому элементу, что и сохраненный хеш.

Однако! Поскольку общие алгоритмы хеширования, такие как MD5 и SHA2, очень быстры, не следует использовать их для хранения паролей. Ознакомьтесь с phpass для реализации bcrypt в PHP.

Надеюсь, это поможет!

person Chris Hepner    schedule 31.07.2011
comment
Это действительно очень помогает, теперь я понимаю (в основном, я думаю), как это работает, но если вы прочитаете часть редактирования в конце моего OP, я все еще не понимаю, как это делает шифрование пароля более безопасным, если соль находится в таблице. Не могли бы они просто попробовать обычный брутфорс и попробовать a.salt, b.salt и т. Д.? - person Adam Smith; 31.07.2011
comment
@ Адам Смит: Давайте попробуем следующее: ЕДИНСТВЕННАЯ вещь, которую делает соление, - это увеличение количества времени, необходимого для взлома одного пароля. Используя различную соль для каждого пароля, вы фактически заставляете хакера создавать радужную таблицу для каждого пароля, а не одну радужную таблицу, которую можно использовать для всей базы данных. - person NotMe; 31.07.2011
comment
@ Адам Смит: Совершенно верно! Это совсем не защищает от атак грубой силы (увеличение длины пароля может потребовать немного больше времени для вычисления хэша, но этого недостаточно, чтобы быть важным). Вот почему вы хотите использовать алгоритм хеширования, который по своей конструкции медленный, например bcrypt, а не тот, который может выполняться сотни миллионов раз в секунду, например MD5 или SHA2. - person Chris Hepner; 31.07.2011
comment
Теперь это имеет смысл. Большое спасибо! Думаю, мне не хватало пары ключевых концепций, чтобы действительно понять, как это работает, я рад, что вы помогли мне понять это, я очень ценю вашу помощь! - person Adam Smith; 31.07.2011

Один использует соль, чтобы злоумышленник не создавал радужную таблицу, например таблица, содержащая все (обычные) пароли и соответствующие хеши, отсортированные (или как-то легко доступные) по хешам. Если у злоумышленника есть такая таблица или он может ее создать, а затем получает вашу базу паролей с несолеными хэшами, он может легко найти пароли даже для всех ваших пользователей сразу.

Если хэши соленые (и злоумышленник получает соль с хешами), он все равно сможет провести ту же атаку (только немного больше работы по вводу соли) - но теперь эта работа по построению радужной таблицы бесполезна. для следующего хэша с другой солью, что означает, что это нужно будет сделать для каждого пользователя снова. Только это и есть цель соли. Атака по словарю на вашу единственную учетную запись по-прежнему требует того же времени, что и раньше, просто радужная таблица бесполезна. (Чтобы что-то сделать против атаки по словарю, см. Ниже.)


Как именно используется соль, зависит от используемого алгоритма. Некоторые алгоритмы хеширования (например, bcrypt, который специально создан для хеширования паролей) имеют специальный входной параметр соли (или сами генерируют соль и включают ее в вывод):

H = bcrypt (пароль, жесткость) или H = bcrypt (соль, пароль, жесткость)

(Первый вариант генерирует саму соль, а второй берет ее извне. Оба включают хэш и параметр твердости в выводе.)

Другие нужно использовать в каком-то особом режиме, чтобы использовать соль. Простым вариантом, который работает для большинства алгоритмов хеширования, было бы использование HMAC с солью в качестве «сообщения». введите пароль как ключ:

HMAC (пароль, соль) = Хеш (пароль ⊕ opad || Хеш (ipad ⊕ пароль || соль))

где opad и ipad - некоторые постоянные значения заполнения.

Затем вы храните соль вместе с хешем. (Для немного более высокого барьера вы можете сохранить хэш в другом месте, чем соль. Но вам все равно понадобится и то, и другое для входа в систему.) Затем для входа в систему вы передадите пароль и сохраненную соль своей хеш-функции и сравните результат с сохраненным хешем. (Большинство библиотек bcrypt имеют встроенную функцию "проверки пароля", которая делает это.)


Для хранения паролей важно использовать медленный алгоритм хеширования, а не быстрый, чтобы избежать (или действительно: замедлить) грубую силу или словарные атаки на пароли, поскольку у большинства людей будет довольно короткий пароли. bcrypt - это алгоритм, созданный специально для этой цели (его медленность регулируется параметром).

Если вы используете быструю хеш-функцию, обязательно повторяйте ее достаточно часто, чтобы снова стать медленной. (Но лучше, на самом деле: используйте bcrypt.)

person Paŭlo Ebermann    schedule 31.07.2011

Хотя у @Chris и @Pualo очень хорошие ответы. Я хотел добавить еще кое-что о солидных паролях, которые не были выражены.

Использование пароля не является настоящим механизмом защиты. Не имеет значения, используете ли вы bcrypt или какой-либо другой механизм. Это просто тактика проволочек, не более того.

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

Кроме того, большинство зомби-машин можно арендовать ...

Тем не менее, причина, по которой вы испытываете трудности, заключается в том, чтобы выиграть время. Пора заметить, что вы были взломаны, исправить это и сообщить своим пользователям о взломе. Вот и все.

Если злоумышленник получил достаточно доступа к вашей базе данных, чтобы вытащить список паролей, то практически гарантировано, что он получил все остальное. Итак, к этому моменту вы уже все потеряли. Единственный вопрос - сколько времени у вас уйдет на то, чтобы заткнуть дыру, сбросить все пароли и сказать им, что они должны сбросить пароли для любой другой учетной записи, которая у них может быть, где они использовали ту же самую. Если вы Sony, то это время, по-видимому, измеряется месяцами, если не годами ...;) Постарайтесь быть немного быстрее.

Итак, хотя это ответственное дело, это только одна часть вашего защитного пояса с инструментами. Если вас взломали, вы можете поспорить, что эти имена пользователей и пароли появятся где-то на сайте в какой-то момент в ближайшем будущем. Надеюсь, к тому времени вы уже прибрались в своем доме.

person NotMe    schedule 31.07.2011
comment
Я рад, что вы тоже ответили, чтобы добавить то, что не было сказано. Как вы сказали, это всего лишь один инструмент в моем арсенале защитных инструментов; у вас есть ссылка, чтобы порекомендовать мне другие передовые методы защиты моих данных или что-то еще, о чем мне следует знать? - person Adam Smith; 31.07.2011
comment
@Adam Smith: Начните здесь: owasp.org В частности, owasp.org/index.php/Category:Principle - person NotMe; 31.07.2011
comment
С помощью bcrypt вы можете указать стоимость. Достаточно ли пары лет на пароль? Не относите его к той же категории, что и хэши сообщений, и не отклоняйте его как просто тактику отсрочки. - person ErikE; 31.07.2011
comment
@ErikE: конечно ... если ваши пользователи хотят тратить столько времени на то, чтобы войти на ваш сайт ... Вы должны поддерживать достаточно низкую стоимость, чтобы ваш сайт оставался отзывчивым на вашем оборудовании. Рассмотрим это так, допустим, я хакер и арендую время в ботнете, который дает мне доступ к сотне тысяч машин. Даже если стоимость хеша составляет 5 секунд (что является долгим временем для входа на сайт), это означает, что я могу генерировать 2 миллиона ключей в минуту. Интересно, сколько мне нужно сгенерировать, чтобы получить столкновение? Учитывая то, что большинство людей используют для паролей, я бы сказал, что не так уж много. - person NotMe; 31.07.2011
comment
@ErikE: Кроме того, не упоминайте о замене букв цифрами и т. Д. Обычные (и даже необычные) словари уже много лет входят в состав словарей. - person NotMe; 31.07.2011
comment
@ErikE: способ увеличить количество итераций без замедления сервера входа в систему - позволить клиенту сделать это: Использует медленный Хеширование паролей на стороне клиента легче атаковать, чем на стороне сервера? Конечно, это возможно только в том случае, если вы можете разработать свой собственный протокол. - person Paŭlo Ebermann; 03.08.2011

Использование соли предотвращает использование предварительно вычисленных радужных таблиц, например, если пользователь использует «Пароль» в качестве пароля, MD5 («Пароль»), SHA1 («Пароль») или WhatEver («Пароль») могут быть хорошо известными результатами. хранится в некоторых радужных таблицах. Если вы используете другое значение соли для каждого человека, называемое nonce, вы получите MD5 (HMAC («Пароль», «RandomSaltValue»)), SHA1 («Пароль», «AnotherRandomSaltValue»), ... что означает два разных хешированные значения пароля для того же начального пароля. Теперь вопрос о хранении этих значений солей ... я думаю, что они могут быть сохранены в базе данных, идея солей состоит в том, чтобы предотвратить атаку в стиле радуги, а не проблему взлома базы данных.

person mmorel    schedule 31.07.2011
comment
Я понимаю, поэтому использование соли в вашем пароле на самом деле не помогает снова использовать методы перебора, которые повторяют каждое возможное значение, оно защищает вас от атак по словарю и тому подобного. В этом есть смысл, я подумал, что соление защищает пароли и от обычного перебора. Это объясняет, что хранимая соль на самом деле не вызывает дополнительных дыр в безопасности. - person Adam Smith; 31.07.2011

Хотя bcrypt значительно замедляет процесс, все же, вероятно, можно будет атаковать вашу схему, если можно будет выполнять множество вычислений параллельно. Я знаю, что это маловероятно, и это действительно должен быть довольно изобретательный злоумышленник, но давайте представим, что защищаемый вами сайт будет содержать фотографии и документы из Зоны 51 :) В этом случае, при достаточном распараллеливании, у вас все равно могут быть проблемы, даже если вы используете bcrypt.

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

Хотя кажется, что bcrypt и даже больше scrypt, похоже, привлекают меньше внимания с точки зрения криптоанализа, чем PBKDF2, изложенное в RSA PKCS # 5. Подробнее см. обсуждение.

person emboss    schedule 31.07.2011

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

РЕДАКТИРОВАТЬ: удалена ошибочная информация. Я буду придерживаться единственного хорошего совета, который у меня был, - не кататься самостоятельно.

person Matt Tsōnto    schedule 31.07.2011
comment
Все возможные значения соли? Вы уверены, что? Мне это кажется немного странным. - person ErikE; 31.07.2011
comment
Если он пробует все возможные значения соли и соль была объединена с помощью XOR, она будет работать с любым паролем. - person Paŭlo Ebermann; 31.07.2011
comment
Я бы поставил +1 за это: Прежде всего, я бы сказал, что с безопасностью очень сложно работать правильно, и что вам действительно следует полагаться на существующие библиотеки, чтобы сделать для вас как можно больше. Но затем -1 для вашей грубой силы при входе в систему. - person Paŭlo Ebermann; 31.07.2011
comment
@ Эмдот: ммм ... нет. Соль хранится. Обычно он хранится в той же записи, что и сам пароль. Когда пользователь вводит свой пароль, вы берете пароль, объединяете его с солью и хешируете. Затем вы сравниваете хеш-значения. Если они совпадают, можно идти. Система НЕ сравнивает все возможные значения хеш-функции, чтобы убедиться, что введенный пароль правильный. Это займет слишком много времени. - person NotMe; 31.07.2011
comment
Прочтите codahale.com/how-to-safely-store-a-password, чтобы получить новую информацию, которая делает ответы и комментарии здесь сомнительными. - person ErikE; 31.07.2011
comment
@ErikE Вот чего я не понимаю о солении ... Значение генерируется случайным образом и нигде не сохраняется, так как же вы можете продолжать повторно использовать ту же соль? И повторение всех возможных значений, похоже, не имеет никакого смысла, поскольку потребуется время, чтобы опробовать их все и как бы победить цель ... - person Adam Smith; 31.07.2011
comment
@Chris Lively Это то, что я хотел бы объяснить ... Если соль хранится в базе данных, то как повысить безопасность пароля, если хакеры, которые получают доступ к базе данных, уже имеют правильную соль для объединения паролей, которые они пробуют с участием? - person Adam Smith; 31.07.2011
comment
@Adam: соление предназначено только для помощи в радужных таблицах (например, кто-то предварительно вычисляет хеши для всех паролей, а затем просто ищет пароли из хеша). С солью злоумышленник должен создать радужную таблицу для каждой отдельной используемой соли (или для всех из них, которая становится больше, чем может храниться на земле, если соль достаточно длинная). - person Paŭlo Ebermann; 31.07.2011
comment
@ Адам: Я на 100% согласен с Пауло. - person NotMe; 31.07.2011
comment
Да, соли @Adam предназначены только для предотвращения радужных атак, которые работают со всем набором данных. - person ErikE; 31.07.2011

А как насчет безопасного хэша и соли для паролей PHP? У него даже есть примеры на PHP.

person Shi    schedule 31.07.2011
comment
@ Paŭlo Ebermann Пожалуйста, не оставляйте ответы, которые должны быть комментариями. Ответы должны пытаться ответить на вопрос. - Разве мой ответ не отвечал на вопрос? Я подумал, что копировать текст сюда снова - не лучшая идея. - person Shi; 31.07.2011
comment
На самом деле, лучший способ - отметить вопрос для закрытия, поставив ссылку на этот вопрос. По сути, это одно и то же. SO автоматически добавит его как комментарий. - person NotMe; 31.07.2011
comment
У меня есть, но есть ключевые концепции, которые мне не хватает, например, как постоянно получать одну и ту же соль (которая генерируется случайным образом). Кажется, что он хранится, так что это ответит на мой вопрос, но тогда как это безопасно, если у людей, пытающихся взломать пароли, уже есть соль? - person Adam Smith; 31.07.2011