Лучший способ хранить пароли в базе данных MYSQL
Да, я знаю, что хранить пароли в виде обычного текста не рекомендуется. Есть ли лучший и простой способ хранения паролей, чтобы приложение оставалось безопасным?
6 ответов
Во-первых, доказано, что md5 и sha1 уязвимы для атак коллизий и могут быть легко представлены в виде радуги (когда они видят, совпадает ли ваш хэш в их базе данных общих паролей).
В настоящее время есть две вещи, которые достаточно безопасны для паролей, которые вы можете использовать.
Первый - это sha512. sha512 является дополнительной версией SHA2. До сих пор не было доказано, что SHA2 уязвим для атак коллизий, и sha512 генерирует 512-битный хэш. Вот пример того, как использовать sha512:
<?php
hash('sha512',$password);
Другой вариант называется bcrypt. bcrypt славится своими надежными хешами. Это, пожалуй, самый безопасный и самый настраиваемый вариант.
Прежде чем вы захотите начать использовать bcrypt, вам нужно проверить, включен ли ваш сервер, введите этот код:
<?php
if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
echo "CRYPT_BLOWFISH is enabled!";
}else {
echo "CRYPT_BLOWFISH is not available";
}
Если он вернет, что он включен, то следующий шаг будет легким. Все, что вам нужно сделать, чтобы зашифровать пароль, это (примечание: для большей гибкости настройки вы должны увидеть это. Как вы используете bcrypt для хеширования паролей в PHP?):
crypt($password, $salt);
Соль - это, как правило, случайная строка, которую вы добавляете в конце всех своих паролей, когда вы их хешируете. Использование соли означает, что если кто-то получит вашу базу данных, он не сможет проверить хэши на наличие общих паролей. Проверка базы данных вызывается с помощью радужной таблицы. Вы должны всегда использовать соль при перемешивании!
Вот мои доказательства уязвимостей атаки SHA1 и MD5:
http://www.schneier.com/blog/archives/2012/10/when_will_we_se.html, http://eprint.iacr.org/2010/413.pdf,
http://people.csail.mit.edu/yiqun/SHA1AttackProceedingVersion.pdf,
http://conf.isi.qut.edu.au/auscert/proceedings/2006/gauravaram06collision.pdf и
Понимание слабости столкновения ша-1
Алгоритмы хеширования, такие как sha1 и md5, не подходят для хранения пароля. Они разработаны, чтобы быть очень эффективными. Это означает, что перебор очень быстрый. Даже если хакер получит копию ваших хешированных паролей, он довольно быстро его взломает. Если вы используете соль, это делает радужные столы менее эффективными, но ничего не делает против грубой силы. Использование более медленного алгоритма делает грубую силу неэффективной. Например, алгоритм bcrypt может быть выполнен настолько медленно, насколько вы пожелаете (просто измените коэффициент работы), и он использует соли для внутренней защиты от радужных таблиц. Я бы пошел с таким подходом или подобным (например, Scrypt или PBKDF2), если бы я был вами.
Сохраните уникальную соль для пользователя (например, сгенерированную из имени пользователя + адрес электронной почты) и сохраните пароль. При входе в систему, получить соль из базы данных и хэш соль + пароль.
Используйте bcrypt для хеширования паролей.
Пароли в базе данных должны храниться в зашифрованном виде. Рекомендуется использовать одностороннее шифрование (хеширование), например SHA2, SHA2, WHIRLPOOL, bcrypt DELETED: MD5 или SHA1. (те, кто старше, уязвимы
В дополнение к этому вы можете использовать дополнительную произвольную строку для каждого пользователя - 'salt':
$salt = MD5($this->createSalt());
$Password = SHA2($postData['Password'] . $salt);
createSalt()
в данном случае это функция, которая генерирует строку из случайных символов.
РЕДАКТИРОВАТЬ: или, если вы хотите больше безопасности, вы можете даже добавить 2 соли: $salt1 . $pass . $salt2
Другой мерой безопасности, которую вы можете предпринять, является инактивация пользователя: после 5 (или любого другого числа) неправильных попыток входа в систему пользователь блокируется на x минут (скажем, 15 минут). Это должно минимизировать успех атак грубой силы.
Лучше всего использовать крипту для хранения пароля в БД
пример кода:
$crypted_pass = crypt($password);
//$pass_from_login is the user entered password
//$crypted_pass is the encryption
if(crypt($pass_from_login,$crypted_pass)) == $crypted_pass)
{
echo("hello user!")
}
документация:
Вы должны использовать одностороннее шифрование (это способ зашифровать значение, чтобы его было трудно перевернуть). Я не знаком с MySQL, но быстрый поиск показывает, что в нем есть функция password(), которая выполняет именно этот тип шифрования. В БД вы будете хранить зашифрованное значение, и когда пользователь захочет аутентифицировать вас, вы получите пароль, который он предоставил, вы зашифруете его, используя тот же алгоритм / функцию, а затем убедитесь, что значение совпадает с паролем, хранящимся в базе данных для этот пользователь. Это предполагает, что связь между браузером и вашим сервером безопасна, а именно то, что вы используете https.