Как вы надежно храните пароль пользователя и соль в MySQL? - PullRequest
16 голосов
/ 01 сентября 2011

Итак, я обнаружил на SO, что вы должны хешировать пароль вместе с «солью». (Статьи можно найти здесь и здесь .)

Вот код:

$password = 'fish';

/* should be "unique" for every user? */
$salt= 'ABC09';

$site_key = 'static_site_key';

hash_hmac('sha1', $password . $salt, $site_key);

А теперь мне нужно сохранить и $password, и $salt в MySQL, например:

+---------+--------+----------+-------+
| user_id |  name  | password |  salt |
+---------+--------+----------+-------+
|    1    | krysis |  fish**  | ABC09 |
+---------+--------+----------+-------+

** fish будет, конечно, хешироваться и не храниться в виде простого текста.

И мне просто интересно, имеет ли смысл на самом деле делать это таким образом, потому что таким образом хакер или кто-то еще будет знать соль? Итак, если они взломают пароль и увидят, что он fishABC09, они автоматически узнают, что пароль fish? Или он «никогда» не сможет взломать пароль, потому что он не знает secret_key, так как он не хранится в базе данных?

Извините, если я не вижу смысла. Я просто всегда использовал sha1 для паролей, и сегодня я нашел эти статьи, в которых говорилось о добавлении salt.

Ответы [ 8 ]

8 голосов
/ 01 сентября 2011

Есть хорошие статьи о правильном хранении паролей. Один из них, например: Хранение паролей - сделано правильно!

Вы должны использовать разные соли для каждого пользователя, но нет необходимости хранить соли отдельно. Смотрите аналогичное обсуждение в другой теме

Кстати, вы, вероятно, не должны использовать sha1, например, Вместо этого sha256 или sha512 - что-то более сильное (по крайней мере, чтобы избежать плохой рекламы). На этот вопрос есть хороший ответ: Насколько небезопасен соленый SHA1 по сравнению с соленым SHA512

6 голосов
/ 01 сентября 2011

Радужные / словарные атаки и соленые пароли - подход еретиков

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

Тем не менее, этот вопрос некоторое время бился в моем черепе (см. Правку) и я хотел бы изложить еретическую точку зрения.

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

Это хорошо работает для процесса паролей NT4, который использует хэши md5 и не использует соль. Но когда соль добавляется к паролю перед хэшированием, тогда радужная таблица бесполезна - вместо поиска md5-хэша «mypass» она должна предварительно вычислить «mypass-random-string_of-letters»

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

но ...

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

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

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

За этим стоит математика. Обычный совет (также предоставленный RSA - ftp.rsa.com/pub/pkcs/pkcs-5v2/pkcs5v2-0.pdf) - это сборка 64-битной соли, храните ее вместе с хешированный пароль Таким образом, вы можете повторно подтвердить пароль, перефразировав его с солью, и отменить хэш практически невозможно.

NB - я могу ошибаться ...

Бит «почти невозможно» происходит из простой математики.

Давайте предположим, что пароль состоит из 8 цифр и содержит 62 возможных символа (буквы, верхний нижний и цифры)

То есть 62 ^ 8 комбинаций, или чуть более 200 миллионов триллионов.

Для грубой силы путем непосредственного вычисления хеша (т.е. составления моих радужных таблиц для соли) я должен увидеть столкновение после 62 ^ 8/2, и, скажем, 100 хешей в секунду, это займет около 12 миллионов дней. , Да дней.

ОК, поэтому даже сохранение хеша с паролем делает задачу нахождения хеша совершенно неосуществимой.

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

Таким образом, пространство поиска вместо 62 ^ 8 действительно меньше. Как маленький? Зависит от пароля "сила".

Существует около 250 000 - 750 000 слов на английском языке (http://oxforddictionaries.com/page/93). Давайте возьмем 500 000 в качестве простого случая. Затем давайте возьмем варианты, которые можно применить - добавить цифру, добавить год, преобразовать гласные в цифры. Это дает нам произнесите 3 возможных новых слова на слово или 2 миллиона возможных паролей.

Генерирование 2 миллионов хешей со скоростью 100 в секунду дает 20000 секунд или 5 часов - в пределах досягаемости любого ноутбука.

Таким образом, если нацеливается конкретный пользователь (root, admin, spolsky и т. Д.), То сохранение соли с паролем немедленно делает возможным взлом.

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

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

Это все компромисс -принуждение людей к использованию 15-значных паролей означает, что все они размещаются на экране или становятся «легко запоминающимися», то есть словами.

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

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

HTH

6 голосов
/ 01 сентября 2011
$username = mysql_real_escape_string($username);
$password = mysql_real_escape_string($password);
$time = time();
$query = "
INSERT INTO user (name, unixcreationtime, passhash) 
VALUES ('$username', '$time', SHA2(CONCAT('$time','$password'),512) ";

Не используйте SHA1, он больше не защищен.
Я предлагаю делать все хеширование в MySQL, чтобы вы могли быть уверены, что в результате хеширования нет разницы.

Выберите пользователя, используя:

$query = "SELECT id FROM user 
          WHERE name = '$username' 
            AND passhash = SHA2(CONCAT(creationdate,'$password'),512) ";
4 голосов
/ 01 сентября 2011

Нет, потому что, когда пароль хешируется, он не выглядит как fishABC09, он выглядит следующим образом: 5f4dcc3b5aa765d61d8327deb882cf99, который является хешем md5.

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

Например: выполнить поиск Google для хэша md5 "password", который: 5f4dcc3b5aa765d61d8327deb882cf99

Много результатов, верно?

Теперь я собираюсь снова создать хеш, я все еще буду использовать «пароль», но я добавлю СОЛЬ, которая является «AHG (* @». Я предполагаю, что единственный ответ будет для этого поста и некоторые бот-скреперы, которые читали этот пост:)

cbe57e92ffbb0086320891b9f979156d

Должно быть только несколько результатов или этот пост, к которому относится этот пост.

Только помни

Просто запомните это ... хэши в одну сторону , поэтому даже если вы получите хеш, вы не знаете, что использовалось для его создания

1 голос
/ 06 апреля 2017

это старая тема, но другие тоже придут сюда, поэтому я постараюсь описать ее очень просто:

если вы делаете хеш (пароль), вы получаете одинаковое хеш-значение для каждого пароля [хеш (пароль) = хеш (пароль)]. если два пользователя имеют один и тот же пароль, вы увидите его, потому что хеш-значения одинаковы. некоторые пароли, такие как «пароль» или «12345678», используются очень часто, например: такое же хеш-значение в вашей базе данных -> может быть, пароль «пароль» или «12345678» (радужная атака).

если вы используете хеш (соль + пароль), вы не получите тот же хеш для тех же паролей, потому что хеш (соль1 + пароль) не является хешем (соль2 + пароль).

hash (x) - это просто математическая функция типа f (x) = y. если вы поставите тот же самый х, вы получите тот же самый у. эта функция должна быть «особой», чтобы быть безопасной. просто не используйте sha1, потому что это больше не безопасно: D

1 голос
/ 07 ноября 2014

Я знаю, что это старо, но для любого, кому удается наткнуться на этот пост ...

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

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

Мне очень нравится таблица здесь: https://github.com/pbhogan/scrypt#why-you-should-use-scrypt

0 голосов
/ 01 сентября 2011

Если хакер получает доступ к вашим PHP-файлам, он может просто добавить почтовую функцию, так что, кто бы ни войти, данные учетной записи будут отправлены по электронной почте хакеру.

Если хакер получает доступ только к базе данных, он не должен получать пароли, явно написанные там, поэтому зашифруйте его перед сохранением.Сохраните его в хеше md5, который нельзя отменить.

Я обычно использую соль на основе имени пользователя или идентификатора пользователя, которую PHP-программа знает, как генерировать для каждого пользователя вместе со static_site_key.

0 голосов
/ 01 сентября 2011

Соль - это случайное число фиксированной длины. Эта соль должна быть разной для каждой сохраненной записи. Он должен храниться в виде открытого текста рядом с хешированным паролем.

С

https://www.owasp.org/index.php/Hashing_Java#Why_add_salt_.3F

...