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

476

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

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

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

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

Crash893
источник
1
Что бы вы ни делали, если вы используете шифрование, не храните ключ в коде, как упоминалось ранее. Это просто плохая практика.
Вуди
12
«Как правильно делать пароли?» это жизненно важный вопрос. Это сложная проблема, и ошибки имеют серьезные последствия (вспомните, что случилось с Tesco и LinkedIn). Я думаю, что этот вопрос должен быть вновь открыт на programmers.stackexchange.com
полковник Panic
2
Лучше придерживаться стандартов - см. En.wikipedia.org/wiki/PBKDF2 Нужно только найти реализацию на своем языке
Борис Треухов
5
На этот вопрос
часто

Ответы:

406

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

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

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

Паоло Бергантино
источник
40
Я имел в виду хранение пароля в базе данных, а не хранение его в другом месте. Если вычеркнуть это предложение из контекста, создается впечатление, что я поддерживаю хранение простых паролей, если вы прочитаете остальное, я, очевидно, этого не сделаю.
Паоло Бергантино
14
Мало того, что я сказал, я направил его на множество постов, которые обсуждают соли и тому подобное ...
Паоло Бергантино
1
@Paolo Bergantino: вы уверены, что в вашем посте нет опечатки? В нем говорится: «В большинстве случаев, с которыми вы столкнетесь (и я, честно говоря, не могу придумать никаких контрпримеров), хранение пароля в базе данных - это правильное решение». ??? Это, кажется, противоречит вашим комментариям
Mitch Wheat
3
То, что сказал Паоло, прямо противоречит само себе. Соленый хеш пароля не является паролем. Хранение соленого хэша пароля в базе данных не сохраняет пароль в базе данных. Тело ответа совершенно уместно, но его первое предложение вводит в заблуждение.
Роберт Россни
40
@ Роберт: Это опасно близко к мелкой семантике, но я все же исправлю это ...
Паоло Бергантино
54

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

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

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

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

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

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

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

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

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

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

Итак, вы должны «засолить» свои пароли. Смотрите статью в Википедии о соли

Смотрите "Как хэшировать данные с солью" C # пример

joej
источник
14
Хороший пост, за исключением одного: md5 и sha1 оба были сломаны. Возможно, вам следует использовать более сильный алгоритм, например, семейство SHA2.
Паоло Бергантино
3
Спасибо Паоло - ты прав. Поскольку использовать SHA2 так же просто, как использовать MD5 и SHA1, используйте более сильный алгоритм хеширования.
Joej
5
SHA-1 не был сломан. Но перефразируя Брюса Шнайера: иди, не беги, в SHA-2.
Ян Бойд
3
«Итак, вы должны« засолить »свои пароли» ... Но соль обычно хранится в базе данных вместе с паролем, так как это поможет? Злоумышленник просто должен добавить соль к словарным фразам атаки, с которыми он тестирует. Как это является более безопасным, чем то, что он не обнаружит повторяющиеся пароли?
trusktr
4
@joej "Тебе никогда ... действительно ... не нужно знать пароль пользователя" - это очень недальновидное предположение. Существует много видов приложений, в которых действительно необходим пароль, который может быть восстановлен. Например, приложение, которое должно часто входить в другую систему с сохраненными учетными данными, предоставленными и обновленными пользователем.
Франциско Сарабосо
29

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

nilamo
источник
6
На мой взгляд, вы всегда должны использовать медленные алгоритмы (например, Blowfish) для хранения паролей. Эта статья является гораздо лучшим ответом: security.stackexchange.com/questions/211/… . Просто поместите это здесь, потому что эта страница все еще появляется высоко в результатах поиска.
Dynom
2
Следуя этому совету по хранению пароля, вы поступите неправильно.
mlissner
27

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

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

Митч Пшеничный
источник
11
Уэйн, посолив перед вычислением хеша, радужный стол эффективно побеждает, при условии, что соль имеет достаточный размер.
Майк Розенблюм
12
@ Уэйн Хартман: Не так. Если значение соли выставлено, то вы должны сгенерировать новую радужную таблицу для этого конкретного значения соли. Смысл радужной таблицы состоит в том, чтобы заранее вычислить значения хеш-функции. И ни у кого не будет радужного стола для его конкретной соли.
Ян Бойд
10

Я бы настоятельно рекомендовал прочитать статьи « Достаточно с таблицами Rainbow»: что нужно знать о безопасных схемах паролей [неработающая ссылка, копия в Интернет-архиве ] и как безопасно хранить пароль .

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

zebrabox
источник
1
@Johan Похоже, что ссылка теперь не работает, это позор. Вот альтернативный codahale.com/how-to-safely-store-a-password
zebrabox
6

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

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

Это может не подойти, если рассматриваемое приложение предназначено исключительно для внутреннего использования.

RPX предоставляет хороший простой способ интегрировать поддержку OpenID в приложение.

Crippledsmurf
источник
Я согласен с тем, что openID отвлекает людей, но для этого приложения это внутренняя база данных для компании, я сомневаюсь, что они хотели бы, чтобы любой пожилой человек заходил в систему. Кроме того, веб-доступ не требуется для этого приложения для правильной работы, поэтому я не хотел бы требовать его.
Crash893
3

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

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

Рэй Лу
источник
1

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

waiwai933
источник
2
Я бы не использовал MD5 для хеширования - он в основном не работает mscs.dal.ca/~selinger/md5collision
zebrabox
3
На самом деле, это не так сломано. Они могут найти одно и то же значение хеш-функции для двух разных файлов. Чего они не могут сделать, так это перевернуть MD5 и получить рабочий пароль.
waiwai933
2
Ну, разве это тоже не будет сломано? Вы просто вводите другой пароль, который генерирует тот же хеш, и вы в нем. Вам не нужно знать оригинальный пароль. Способ исправить это, если вы солите пароль перед хэшированием.
mjuarez
2
@mjuarez, если вы добавите соль в пароль, прежде чем использовать MD5, столкновение не имеет значения, потому что вы не можете использовать другой пароль
WiiMaxx