Как безопасно хранить пароль пользователя и соль в MySQL?
Итак, я узнал о том, что вы должны записать пароль вместе с "солью". (Статьи можно найти здесь и здесь.)
Здесь код:
$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
.
Ответы
Ответ 1
Есть хорошие статьи о правильном хранении паролей. Один из них, например: Хранение паролей - сделано правильно!
Вы должны использовать различную соль для каждого пользователя, но нет необходимости хранить соли отдельно. См. Аналогичное обсуждение в другом потоке
Кстати, вы, вероятно, не должны использовать sha1, но, к примеру, sha256 или sha512 чем-то более сильным (по крайней мере, чтобы избежать плохой рекламы). Там есть хороший ответ по этому поводу: Как небезопасный соленый SHA1 по сравнению с соленым SHA512
Ответ 2
Радуга/Словарь Атаки и соленые пароли - подход еретиков
Пароли не должны храниться в вашей базе данных. Не сворачивайте свой собственный механизм аутентификации - вы почти наверняка ошибутесь. Используйте Kereberos для ценных вещей, и хорошо, что у меня нет хорошего предложения.
Тем не менее, этот вопрос в течение некоторого времени искажается в моем черепе (см. правки)
и я хотел бы поставить еретическую точку зрения.
Таблицы Rainbow так называются из-за того, как используется механизм поиска (цепочка), но они просто являются атаками словаря. Миллионы словарных слов и общих фраз передаются вперед, а затем используются для сравнения похищенных хэшированных паролей.
Это хорошо работало для процесса паролей NT4, в котором использовались хэши md5 и соль. Но
когда соль добавляется к паролю перед хэшированием, тогда таблица радуги бесполезна - вместо поиска хэша md5 "mypass" он должен прекомпопировать "mypass-random-string_of-letters"
Невозможно догадаться, какая соль кто-то будет использовать, поэтому соление делает радужные столы как общие, использовать в любом месте против любого серверного решения, мертвого в воде.
но...
Это только один случай использования - конечно, большая угроза, безусловно, защита. Но
соли. Вы должны держать соль вокруг, когда вы хотите пройти аутентификацию в следующий раз, когда пользователь входит в систему. Они отправляют свой открытый текст (через ssl!), Вы добавляете соль и хэш, компрометируете хэш, хранящийся в базе данных. Но если вы не храните соль с паролем, вы не можете этого сделать, а errr... no login
Но мы не только защищаемся от людей, проходящих вокруг стола, от которого можно взломать NT4 passwrods. Мы должны защищать наших пользователей индивидуально.
Соль добавляет защиту двух факторов к паролям - даже с хешем злоумышленник будет нуждаться в соли, чтобы иметь возможность взломать ее. Но стандартный совет просто отдает две защитные меры. Возможно, это разумно, но я не уверен.
За этим немного математики. Обычный совет (данный RSA также - ftp.rsa.com/pub/pkcs/pkcs-5v2/pkcs5v2-0.pdf) - это собрать 64-битную соль, сохранить ее с помощью
hashed пароль. Таким образом, вы можете повторно подтвердить пароль, повторно нажав соль, и изменить хеш почти невозможно.
NB - я могу ошибаться здесь...
Бит "рядом с невозможным" - это простая математика.
Давайте возьмем 8-значный пароль, содержащий 62 возможных символа (буквы, верхний нижний и цифры)
Thats 62 ^ 8 комбинаций или чуть более 200 миллионов триллионов.
Чтобы грубо заставить это, вычислив хеш напрямую (т.е. сделав мои солевые конкретные таблицы радуги), я должен увидеть столкновение после 62 ^ 8/2 и, скажем, 100 хешей в секунду, это займет около 12 миллионов дней, Да, дни.
ОК, поэтому даже сохранение хэша с паролем делает задачу поиска хеша совершенно неосуществимой.
Однако в вышеизложенном имеются некоторые предположения. Во-первых, пароль является случайным выбором диапазона 62 ^ 8. На практике большинство паролей гораздо слабее - радужные таблицы на самом деле не основаны на всех возможностях 62 ^ 8 - они построены из словарей и реальных таблиц пароля, найденных на протяжении многих лет.
Таким образом, пространство поиска, а не 62 ^ 8, действительно меньше. Как мало? Это зависит от пароля "сила".
В английском языке (http://oxforddictionaries.com/page/93) имеется около 250 000 - 750 000 слов. Давайте возьмем 500 000 в качестве простого случая. Затем давайте возьмем варианты, которые можно применить - добавьте цифру, добавьте год, конвертируйте гласные в цифры. Это дает нам сказать 3 возможных новых слова на слово, или 2 миллиона возможных паролей.
Генерация 2-х миллионов хешей при 100/сек дает 20 000 секунд или 5 часов - хорошо в пределах диапазона любого ноутбука.
Таким образом, если есть конкретный пользователь, который нацеливается (root, admin, spolsky и т.д.), то сохранение соли с помощью пароля немедленно делает возможной взлом.
Сохранение соли в стороне от пароля увеличивает сложность трещины - не в какой-либо математической манере, просто в затруднении с получением соли и пароля. Можно предусмотреть отдельный сервер, который просто использует открытый текст, имя пользователя и хеш, и просматривает
соль, используемая для этой даты, и возвращает 1/0
Итак, короче говоря, если вы храните соль с паролем, и кто-то обращается к паролям, то в зависимости от силы пароля каждый пароль может быть взломан в течение разумного промежутка времени. Различная соль для каждого пользователя защищает всех других пользователей, но если вы после определенной учетной записи, это не имеет значения. Если хакер только после одного пароля, то сохранение соли с паролем делает возможной трещину. Сохранение вращающейся соли в другом месте из таблицы паролей означает, что хакеру теперь нужно два перехвата данных, чтобы взломать пароль, потому что без соли любая атака обречена на тысячи лет работы.
Все это означает, что люди вынуждены использовать 15-значные пароли, потому что все они получают сообщение об этом на экране или становятся "легко запоминающимися", то есть словами.
В этот момент вы также можете перейти на Kerberos или аналогичный - если данные, которые вы защищаете, ценны, пользователи поймут и рассмотрят это. Если нет, то почему мы беспокоимся.
Но я по-прежнему рекомендую вам не реализовывать собственный auth mechansim. Используйте Kerberos, используйте полупубличную PKI, не катитесь самостоятельно. Я понятия не имею, как сказать, что мой сервер просто поменял RAM, удерживая мою соль на диске, и это только одна ошибка, о которой я могу сразу придумать при перелибе моей собственной аутентификации.
НТН
Ответ 3
Нет, потому что когда пароль становится хэшированным, он не выглядит как fishABC09
, он выглядит так: 5f4dcc3b5aa765d61d8327deb882cf99
, который является хешем md5.
Чтобы получить доступ к вашей системе, даже если они знают хэш, ее нельзя отменить. Мы используем соли, чтобы добавить сложность в наши хеши и предотвратить поиск хэшей в радужных таблицах.
Например: Сделайте поиск Google для хеша md5 "password", который: 5f4dcc3b5aa765d61d8327deb882cf99
Достаточно много результатов?
Теперь я собираюсь создать хэш снова, я все равно буду использовать "пароль", но я добавлю СОЛЬ, который является "AHG (* @". Я предполагаю, что единственным ответом будет этот пост и некоторые бот-скребки, которые прочитали это сообщение:)
cbe57e92ffbb0086320891b9f979156d
Должно быть только несколько результатов или этот пост, который является этим сообщением.
Просто запомните
Просто запомните это... хеши в один конец, поэтому, даже если вы получите хэш, вы не знаете, что было использовано для его создания
Ответ 4
$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) ";
Ответ 5
Я знаю, что это старо, но для тех, кому удается наткнуться на этот пост...
Что вы действительно пытаетесь сделать HMAC. Попытка сделать это сама создает проблемы. Вы можете частично вычислить хеши, что уменьшает количество усилий, необходимых для угадывания пароля, например. HMAC решает эти проблемы.
Лучше все еще будет scrypt или bcrypt. HMAC все еще часто использует алгоритмы хэша, которые разработаны для быстрого и легкого вычисления; существует даже аппаратная реализация многих хэш-алгоритмов. bcrypt является дорогостоящим вычислительным процессом, а scrypt - интенсивным. Оба делают вещи сложнее для злоумышленника, но, в частности, в scrypt очень сложно создавать аппаратные устройства для взлома пароля.
Мне очень нравится диаграмма здесь: https://github.com/pbhogan/scrypt#why-you-should-use-scrypt
Ответ 6
Соль представляет собой случайное число фиксированной длины. Эта соль должна отличаться для каждой сохраненной записи. Он должен быть сохранен как чистый текст рядом с хешированным паролем.
С
https://www.owasp.org/index.php/Hashing_Java#Why_add_salt_.3F
Ответ 7
Если хакер получает доступ к вашим файлам PHP, он может просто добавить почтовую функцию, поэтому любой, кто входил в систему, детали аккаунта отправляются хакерам по электронной почте.
Если хакер получает доступ только к базе данных, он не должен получать явно написанные там пароли, поэтому перед его сохранением склеит. Сохраните его в хеше md5, который нельзя отменить.
Обычно я использую соль на основе имени пользователя или userID, что PHP-программа знает, как создавать для каждого пользователя вместе с static_site_key.
Ответ 8
его старая тема, но другие придут сюда тоже, поэтому я попытаюсь описать это очень легко:
если вы используете hash (password), вы получаете одинаковое значение hashvalue для каждого пароля [hash (password) = hash (password)]. если у двух пользователей одинаковый пароль, вы увидите это, потому что хеш-значения одинаковы. некоторые пароли, такие как "пароль" или "12345678", принимаются очень часто: одинаковое значение hashvalue в вашей базе данных → возможно, пароль "пароль" или "12345678" (радужная атака).
Если вы используете hash (salt + password), вы не получаете одинаковый хэш для тех же паролей, потому что хеш (salt1 + password) не является хешем (salt2 + password).
hash (x) является просто математической функцией, такой как f (x) = y. если вы поместите тот же x, вы получите тот же y. эта функция должна быть "особой", чтобы быть в безопасности. просто не используйте sha1, потому что он не безопасен больше: D