Какой метод / тип данных вы предпочитаете для хранения паролей в базе данных (желательно SQL Server 2005). В некоторых наших приложениях я делал это сначала с использованием библиотек шифрования .NET, а затем сохранял их в базе данных как двоичные (16). Это предпочтительный метод, или мне следует использовать другой тип данных или выделять больше места, чем 16?
Предпочтительный метод хранения паролей в базе данных
Ответы (10)
Я сохраняю соленый хэш-эквивалент пароля в базе данных и никогда сам пароль, а затем всегда сравниваю хеш-код с сгенерированным из того, что передал пользователь.
Слишком опасно когда-либо где-либо хранить буквальные данные пароля. Это делает восстановление невозможным, но когда кто-то забывает или теряет пароль, вы можете выполнить несколько проверок и создать новый пароль.
varchar. Последний кусок хорошего обдумывания их части - это определение формата их хэш-строки, в которой соль включается в строку.
- person Ian Boyd; 19.11.2013
Предпочтительный метод: никогда не храните пароли в своей БД. Только хеши оного. Посолить по вкусу.
Я делаю то же самое, что вы описали, за исключением того, что он хранится как строка. I Base64 кодирует зашифрованное двоичное значение. Объем выделяемого пространства зависит от алгоритма шифрования / надежности шифра.
Я думаю, вы делаете это правильно (учитывая, что вы используете Salt).
- хранить хэш соленого пароля, например bcrypt (nounce + pwd). Вы можете предпочесть bcrypt, а не SHA1 или MD5, потому что он может быть настроен на интенсивную загрузку ЦП, что увеличивает время атаки методом перебора.
- добавить капчу в форму входа после нескольких ошибок входа (чтобы избежать атак методом перебора)
- если в вашем приложении есть ссылка «забыл свой пароль», убедитесь, что оно не отправляет новый пароль по электронной почте, а вместо этого должно отправлять ссылку на (защищенную) страницу, позволяющую пользователю определить новый пароль (возможно, только после подтверждения некоторой личной информации, такой как, например, дата рождения пользователя). Кроме того, если ваше приложение позволяет пользователю определять новый пароль, убедитесь, что вы требуете от пользователя подтверждения текущего пароля.
- и, очевидно, защитите форму входа (обычно с HTTPS) и сами серверы
Благодаря этим мерам пароли ваших пользователей будут достаточно хорошо защищены от:
- => офлайн словарные атаки
- => атаки по живому словарю
- => атаки отказа в обслуживании
- => Атаки всякие!
Поскольку результатом хеш-функции является последовательность байтов в диапазоне от 0 до 255 (или от -128 до 127, в зависимости от подписи вашего 8-битного типа данных), сохранение его как необработанного двоичного поля имеет наибольший смысл. , так как это наиболее компактное представление и не требует дополнительных шагов кодирования и декодирования.
Некоторые базы данных или драйверы не имеют большой поддержки двоичных типов данных, или иногда разработчики просто недостаточно знакомы с ними, чтобы чувствовать себя комфортно. В этом случае допустимо использование кодировки двоичного кода в текст, например Base-64 или Base-85, и сохранение результирующего текста в символьном поле.
Размер необходимого поля определяется хэш-функцией, которую вы используете. MD5 всегда выводит 16 байтов, SHA-1 всегда выводит 20 байтов. Выбрав хеш-функцию, вы обычно застреваете на ней, поскольку для ее изменения требуется сброс всех существующих паролей. Итак, использование поля переменного размера ничего вам не даст.
Что касается «наилучшего» способа выполнения хеширования, я попытался дать много ответов на другие вопросы SO по этой теме:
- Шифрование паролей
- Шифрование паролей
- Шифрование паролей в .NET
- Соль
- Соль: секретно или открыто?
- Итерации хеширования а>
Я использую sha-хеш имени пользователя, guid в веб-конфигурации и пароль, хранящийся как varchar (40). Если они хотят перебором / словарём, им также нужно будет взломать веб-сервер для поиска гида. Имя пользователя нарушает создание радужной таблицы по всей базе данных, если они действительно находят пароль. Если пользователь хочет изменить свое имя пользователя, я одновременно сбрасываю пароль.
System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(
username.ToLower().Trim(),
ConfigurationManager.AppSettings("salt"),
password
);
Простого хеша пароля или даже (соль + пароль), как правило, недостаточно.
видеть:
и
http://gom-jabbar.org/articles/2008/12/03/why-you-should-use-bcrypt-to-store-your-passwords
Оба рекомендуют алгоритмы bcrypt. Бесплатные реализации для большинства популярных языков можно найти в Интернете.
Вы можете использовать несколько хэшей в своей базе данных, это требует немного дополнительных усилий. Однако это того стоит, если вы думаете, что есть малейшая вероятность, что вам понадобится поддержка дополнительных форматов в будущем. Я часто использую пароли вроде
{hashId} $ {salt} $ {хешированный пароль}
где «hashId» - это просто некоторое число, которое я использую для внутреннего использования, чтобы распознать, например, что я использую SHA1 с определенным шаблоном хеширования; «соль» представляет собой случайную соль, закодированную в кодировке base64; а «хешированный пароль» - это хеш в кодировке base64. Если вам нужно перенести хэши, вы можете перехватить людей со старым форматом пароля и заставить их изменить свой пароль при следующем входе в систему.
Как уже упоминали другие, вы хотите быть осторожными со своими хэшами, так как легко сделать что-то, что действительно небезопасно, например, H (соль, пароль) намного слабее, чем H (пароль, соль), но в то же время вы хотите уравновешивайте усилия, вложенные в это, с ценностью содержания сайта. Я часто использую H (H (пароль, соль), пароль).
Наконец, стоимость использования паролей в кодировке base64 невелика по сравнению с преимуществами возможности использовать различные инструменты, которые ожидают текстовые данные. Да, они должны быть более гибкими, но готовы ли вы сказать своему боссу, что он не может использовать свой любимый сторонний инструмент, потому что вы хотите сэкономить несколько байтов на запись? :-)
Отредактировано, чтобы добавить еще один комментарий: если бы я предложил намеренно использовать алгоритм, который сжигал бы даже 1/10 секунды хеширования каждого пароля, мне бы повезло, если бы меня просто высмеяли из офиса моего босса. (Не так повезло? Он записал бы что-нибудь, чтобы обсудить в моем следующем ежегодном обзоре.) Сжечь это время - не проблема, когда у вас десятки или даже сотни пользователей. Если вы набираете 100 тыс. Пользователей, как правило, в систему одновременно входят несколько человек. Вам нужно что-то быстрое и сильное, а не медленное и сильное. "А как насчет информации о кредитной карте?" в лучшем случае неискренне, поскольку хранимая информация о кредитных картах не должна находиться рядом с вашей обычной базой данных и в любом случае будет зашифрована приложением, а не отдельными пользователями.
Если вы работаете с ASP.Net, вы можете использовать встроенный API членства.
Он поддерживает множество типов хранилищ, в том числе; односторонний хэш, двустороннее шифрование, md5 + соль. http://www.asp.net/learn/security для получения дополнительной информации.
Если вам не нужно ничего особенного, это отлично подходит для веб-сайтов.
Если вы не используете ASP.Net, вот хорошая ссылка на несколько статей от 4guys и codeproject.
http://aspnet.4guysfromrolla.com/articles/081705-1.aspx http://aspnet.4guysfromrolla.com/articles/103002-1.aspx http://www.codeproject.com/KB/security/SimpleEncryption.aspx < / а>
Поскольку ваш вопрос касается способа и размера хранения, я отвечу на него.
Тип хранилища может быть двоичным или текстовым (наиболее распространенным является base64). Двоичный формат меньше, но мне легче работать с текстом. Если вы выполняете посол для каждого пользователя (различная соль для каждого пароля), тогда проще сохранить соль + хеш как одну комбинированную строку.
Размер зависит от алгоритма хеширования. Выходные данные MD5 всегда 16 байтов, SHA1 всегда 20 байтов. SHA-256 и SHA-512 составляют 32 и 64 байта соответственно. Если вы используете кодировку текста, вам потребуется немного больше места для хранения в зависимости от метода кодирования. Я предпочитаю использовать Base64, потому что хранение относительно дешево. Base64 потребуется примерно на 33% больше поля.
Если у вас есть посол для каждого пользователя, вам также понадобится место для хеша. Собирая все вместе 64-битная соль + хэш SHA1 (160 бит), кодировка base64 занимает 40 символов, поэтому я сохраняю его как char (40).
Наконец, если вы хотите сделать это правильно, вам следует использовать не один хэш, а функцию получения ключа, такую как RBKDF2. Хеши SHA1 и MD5 безумно быстрые. Даже однопоточное приложение может хэшировать от 30 до 50 тысяч паролей в секунду, что на четырехъядерном компьютере составляет до 200 тысяч паролей в секунду. Графические процессоры могут хэшировать в 100-1000 раз больше паролей в секунду. С такой скоростью атаки методом грубой силы становятся приемлемым методом вторжения. RBKDF2 позволяет вам указать количество итераций для точной настройки того, насколько «медленным» будет ваше хеширование. Дело не в том, чтобы поставить систему на колени, а в том, чтобы выбрать количество итераций, чтобы вы ограничили верхний предел пропускной способности хеширования (скажем, 500 хешей в секунду). В будущем можно будет указать количество итераций в поле пароля (итерации + соль + хеш). Это позволит увеличить количество итераций в будущем, чтобы идти в ногу с более мощными процессорами. Чтобы быть еще более гибким, используйте varchar, чтобы в будущем разрешить потенциально большие / альтернативные хеши.
Реализация .Net - это RFC2892DeriveBytes http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx