Предпочтительный метод хранения паролей в базе данных

StackOverflow https://stackoverflow.com/questions/615704

Вопрос

Какой метод/тип данных вы предпочитаете хранить пароли в базе данных (предпочтительно SQL Server 2005).В некоторых наших приложениях я использую библиотеки шифрования .NET, а затем сохраняю их в базе данных в двоичном виде(16).Является ли этот метод предпочтительным или мне следует использовать другой тип данных или выделить больше места, чем 16?

Это было полезно?

Решение

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

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

Другие советы

Предпочтительный метод: никогда не храните пароли в вашей БД. Только его хеши. Добавить соль по вкусу.

Я делаю то же, что вы описали, за исключением того, что он хранится в виде строки. Я Base64 кодирую зашифрованное двоичное значение. Объем выделяемого пространства зависит от алгоритма шифрования / надежности шифра.

Я думаю, что вы все делаете правильно (учитывая, что вы используете Salt ) .

<Ол>
  • хранит хэш соленого пароля, например, bcrypt (nounce + pwd). Вы можете предпочесть bcrypt, а не SHA1 или MD5, потому что он может быть настроен так, чтобы интенсивно использовать процессор, что увеличивает длительность атаки методом грубой силы.
  • добавьте капчу в форму входа после нескольких ошибок входа (чтобы избежать атак методом перебора)
  • если в вашем приложении " забыли мой пароль " ссылку, убедитесь, что он не отправляет новый пароль по электронной почте, но вместо этого он должен отправить ссылку на (защищенную) страницу, позволяющую пользователю определить новый пароль (возможно, только после подтверждения какой-либо личной информации, такой как рождение пользователя) дата, например). Кроме того, если ваше приложение позволяет пользователю определить новый пароль, убедитесь, что вы запрашиваете у пользователя подтверждение текущего пароля.
  • и, очевидно, защитите форму входа (обычно с HTTPS) и сами серверы
  • Благодаря этим мерам пароли вашего пользователя будут довольно хорошо защищены от:

    <Ол> <Литий> = & GT; автономные атаки по словарю <Литий> = & GT; живые атаки по словарю <Литий> = & GT; атаки типа "отказ в обслуживании" <Литий> = & GT; всевозможные атаки!

    Поскольку результатом хэш-функции является последовательность байтов в диапазоне от 0 до 255 (или от -128 до 127, в зависимости от знаковости вашего 8-битного типа данных), сохранение ее в виде необработанного двоичного поля имеет наибольший смысл. , поскольку это наиболее компактное представление и не требует дополнительных шагов кодирования и декодирования.

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

    Размер необходимого поля определяется используемой вами хэш-функцией.MD5 всегда выводит 16 байт, SHA-1 всегда выводит 20 байт.После того, как вы выберете хеш-функцию, вы обычно застрянете с ней, поскольку для ее изменения требуется сброс всех существующих паролей.Итак, использование поля переменного размера ничего вам не даст.


    Что касается «лучшего» способа выполнения хеширования, я попытался дать множество ответов на другие вопросы SO по этой теме:

    Я использую хэш sha имени пользователя, guid в веб-конфигурации и пароль, хранящийся в виде varchar (40). Если они хотят использовать грубую силу / словарь, им также необходимо взломать веб-сервер для руководства. Имя пользователя прерывается, создавая радужную таблицу по всей базе данных, если они действительно находят пароль. Если пользователь хочет изменить свое имя пользователя, я одновременно сбрасываю пароль.

    System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(
        username.ToLower().Trim(),
        ConfigurationManager.AppSettings("salt"),
        password
    );
    

    Простого хеша пароля или даже (соль + пароль) обычно недостаточно.

    видеть:

    http://www.matasano.com/log/958/enough-with-the-rainbow-tables-what-you-need-to-know-about-secure-password-schemes/

    и

    http://gom-jabbar.org/articles/2008/12/03/why-you-should-use-bcrypt-to-store-your-passwords

    Оба рекомендуют алгоритмы bcrypt.Бесплатные реализации можно найти в Интернете для большинства популярных языков.

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

    {hashId} $ {salt} $ {хешированный пароль}

    где " hashId " это просто какое-то число, которое я использую внутренне, чтобы распознать, что, например, я использую SHA1 с определенным шаблоном хеширования; & Quot; соль & Quot; случайная соль в кодировке base64; и "хешированный пароль"; является base64-закодированным хешем Если вам нужно перенести хэши, вы можете перехватить людей со старым форматом пароля и заставить их изменить свой пароль при следующем входе в систему.

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

    Наконец, стоимость использования паролей в кодировке base64 невелика по сравнению с преимуществами возможности использования различных инструментов, которые ожидают текстовые данные. Да, они должны быть более гибкими, но готовы ли вы сказать своему боссу, что он не может использовать свой любимый сторонний инструмент, потому что вы хотите сэкономить несколько байтов на запись? : -)

    Отредактировано, чтобы добавить еще один комментарий: если бы я сознательно предложил использовать алгоритм, который хранил даже 1/10 секунды хэширования каждого пароля, мне бы посчастливилось просто посмеяться из кабинета моего босса. (Не так ли повезло? Он записал бы что-нибудь, чтобы обсудить это в моем следующем ежегодном обзоре.) Сжигание этого времени не проблема, когда у вас десятки или даже сотни пользователей. Если вы продвигаете 100 тыс. Пользователей, у вас будет одновременно несколько пользователей. Вам нужно что-то быстрое и сильное, а не медленное и сильное. & Quot; а как насчет информации о кредитной карте? & Quot; в лучшем случае нечестно, поскольку хранимая информация о кредитной карте не должна находиться рядом с вашей обычной базой данных, и в любом случае будет зашифрована приложением, а не отдельными пользователями.

    Если вы работаете с 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

    Поскольку ваш вопрос касается способа хранения & amp; Размер я буду решать это.

    Тип хранилища может быть либо двоичным, либо текстовым представлением (чаще всего используется base64). Двоичный файл меньше, но мне легче работать с текстом. Если вы делаете засоление для каждого пользователя (разные соли для одного пароля), тогда проще хранить соль + хеш как одну объединенную строку.

    Размер зависит от алгоритма хеширования. Вывод MD5 всегда составляет 16 байтов, SHA1 всегда составляет 20 байтов. SHA-256 & amp; SHA-512 32 & amp; 64 байта соответственно. Если вы используете кодировку текста, вам потребуется немного больше места для хранения в зависимости от метода кодирования. Я склонен использовать Base64, потому что хранилище относительно дешево. Base64 будет требовать примерно на 33% больше поля.

    Если у вас есть посол пользователя, вам также понадобится место для хеша. Собирая все вместе, 64-битная соль + SHA1-хэш (160-битный), закодированный в base64, занимает 40 символов, поэтому я сохраняю его как char (40).

    И наконец, если вы хотите сделать все правильно, вы должны использовать не один хеш, а функцию вывода ключа, например RBKDF2. Хэши SHA1 и MD5 безумно быстрые. Даже однопоточное приложение может хэшировать от 30 до 50 тысяч паролей в секунду, то есть до 200 тысяч паролей в секунду на четырехъядерном компьютере. Графические процессоры могут хэшировать от 100x до 1000x столько же паролей в секунду. При таких скоростях атака с использованием грубой силы становится приемлемым методом вторжения. RBKDF2 позволяет вам указать количество итераций, чтобы настроить, как «медленно». ваше хеширование Дело не в том, чтобы поставить систему на колени, а в том, чтобы выбрать количество итераций, чтобы ограничить верхний предел пропускной способности хэша (скажем, 500 хэшей в секунду). В будущем метод доказательства будет включать количество итераций в поле пароля (итерации + соль + хеш). Это позволило бы увеличить количество итераций в будущем, чтобы идти в ногу с более мощными процессорами. Чтобы быть еще более гибким, используйте varchar, чтобы разрешить потенциально большие / альтернативные хэши в будущем.

    .Net - это RFC2892DeriveBytes. http://msdn.microsoft.com/en-us /library/system.security.cryptography.rfc2898derivebytes.aspx

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top