Лучший способ сохранить пароль в базе данных

Я работаю над проектом, который должен иметь аутентификацию (имя пользователя и пароль)

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

Я использую С# и подключаюсь к 2008 Express-серверу. Может ли кто-нибудь предложить (с таким количеством примеров, насколько это возможно), какой лучший способ хранить данные этого типа?

PS Я открыт для идеи, что эта информация не будет храниться в базе данных, если может быть предоставлена хорошая причина

Ответ 1

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

Итак, хотя хорошо, что вы думаете об этом, и это хороший вопрос, на самом деле это дубликат этих вопросов (по крайней мере):

Чтобы немного разъяснить бит сосания, опасность простое хеширование пароля и сохранение этого в том, что, если нарушитель захватывает вашу базу данных, они все равно могут использовать так называемые радужные таблицы, чтобы иметь возможность "расшифровать" пароль (по крайней мере, те, что отображаются в таблице радуги). Чтобы обойти это, разработчики добавили salt к паролям, которые при правильном выполнении делают радужные атаки просто неосуществимыми. Обратите внимание, что распространенное заблуждение состоит в том, чтобы просто добавить одну и ту же уникальную и длинную строку ко всем паролям; в то время как это не ужасно, лучше добавлять уникальные соли к каждому паролю. Подробнее об этом читайте.

Ответ 2

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

Хеш: Храните пароли пользователей в режиме хэширования (одностороннее шифрование) с помощью сильной хэш-функции. Поиск "С# encrypt паролей" дает массу примеров.

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

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

Как его использовать: Но, как вы говорите, как я могу использовать этот размятый пароль, хранящийся в базе данных?

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

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

Дополнительный кредит:

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

Ответ: Да... да, они могут.

Итак, вы должны "солить" свои пароли. См. Статья в Википедии о соле

См. "Как хэш-данные с солью" Пример С#

Ответ 3

В качестве затвердевшего ключа хеш-ключа с использованием безопасного алгоритма, такого как sha-512.

Ответ 4

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

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

Ответ 5

Я настоятельно рекомендую прочитать статьи Достаточно с таблицами Rainbow: что вам нужно знать о схемах безопасного пароля [dead link, копировать в интернет-архиве и Как безопасно хранить пароль.

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

Ответ 6

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

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

Возможно, это не подходит, если рассматриваемая заявка предназначена исключительно для внутреннего использования, хотя

RPX обеспечивает удобный простой способ для интеграции поддержки OpenID в приложение.

Ответ 7

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

Все было построено для этих целей, посмотрите членство asp.net

Ответ 8

Я бы получил пароль MD5/SHA1, если вам не нужно менять хэш. Когда пользователи входят в систему, вы можете просто зашифровать указанный пароль и сравнить его с хэшем. Конфликты хэша практически невозможны в этом случае, если только кто-то не получит доступ к базе данных и не увидит хэш, у которого уже есть столкновение.