Как лучше всего хранить информацию о пользователе и логин и пароль пользователя - PullRequest
30 голосов
/ 04 июня 2009

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

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

Ответы [ 8 ]

38 голосов
/ 04 июня 2009

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

РЕДАКТИРОВАТЬ : ОП ответил, что он понимает вышеуказанную проблему.

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

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

18 голосов
/ 04 июня 2009

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

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

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

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

По возможности, избегайте использования собственного механизма аутентификации по паролю; использовать существующее решение, такое как bcrypt.

Отличное объяснение того, как обращаться с паролями, и что вам нужно беспокоиться, можно найти на http://www.matasano.com/log/958/enough-with-the-rainbow-tables-what-you-need-to-know-about-secure-password-schemes.

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

14 голосов
/ 04 июня 2009

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

8 голосов
/ 04 июня 2009

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

Я бы сказал, что большую часть времени я буду делать что-то подобное в одной таблице:

UserID, FirstName, LastName, Email, Password, TempPassword

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

РЕДАКТИРОВАТЬ - Вы знаете, что я только что подумал. Если вы создадите индекс для имени пользователя или поля электронной почты (в зависимости от того, что вы предпочитаете), это почти полностью устранит недостаток производительности, связанный с созданием такого количества столбцов в пользовательской таблице. Я говорю это потому, что всякий раз, когда вы входите в систему, предложение WHERE будет очень быстро находить имя пользователя, если у него есть индекс, и не будет иметь значения, если у вас есть 100 столбцов в этой таблице. Так что я изменил свое мнение. Я бы положил все это в один стол. ;)

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

4 голосов
/ 04 июня 2009

Будут ли все эти данные всегда иметь отношение 1: 1 с пользователем? Если вы можете отказаться от предоставления пользователям нескольких адресов, телефонных номеров и т. Д., Вы можете разбить личную информацию на отдельную таблицу.

3 голосов
/ 04 июня 2009

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

Если необходимо хранить учетные данные:

  • Не храните обратимую форму; хранить хэш, используя распознанный алгоритм, такой как SHA-256. Используйте криптографическое программное обеспечение из авторитетного заслуживающего доверия источника - НЕ ПЫТАЙТЕСЬ СДЕЛАТЬ СВОЮ СОБСТВЕННОСТЬ, ТЫ СКОЛЬКО ПОЛУЧИТЕ ЭТО НЕПРАВИЛЬНО.
  • Для каждого набора учетных данных храните соль вместе с хешированными данными; это используется для «простого» хеширования, так что два идентичных пароля не производят один и тот же хеш - так как это выдает, что пароли одинаковы.
  • Используйте безопасный генератор случайных чисел. Слабая случайность - причина номер один ошибок шифрования, а не алгоритмов шифрования.

Если вам необходимо сохранить обратимые учетные данные:

  • Выберите хороший алгоритм шифрования - AES-256, 3DES (от даты) или шифр с открытым ключом. Используйте криптографическое программное обеспечение из авторитетного заслуживающего доверия источника - НЕ ПЫТАЙТЕСЬ СДЕЛАТЬ СВОЮ СОБСТВЕННОСТЬ, ТЫ СКОЛЬКО ПОЛУЧИТЕ ЭТО НЕПРАВИЛЬНО.
  • Для каждого набора учетных данных храните соль (незашифрованную) вместе с зашифрованными данными; это используется для «заправки» шифровального шифра таким образом, что два идентичных пароля не выдают одинаковый текст шифра - поскольку это дает возможность идентифицировать пароли одинаковыми.
  • Используйте безопасный генератор случайных чисел. Слабая случайность - причина номер один ошибок шифрования, а не алгоритмов шифрования.
  • Храните ключи шифрования / дешифрования отдельно от базы данных в защищенном файле O / S, доступном только для профиля времени выполнения ваших приложений. Таким образом, если ваша БД взломана (например, путем внедрения SQL-кода), ваш ключ не будет автоматически уязвим, так как для этого потребуется доступ к жесткому диску в целом. Если ваша операционная система поддерживает шифрование файлов, привязанное к профилю, используйте его - оно может помочь только в общем случае и прозрачно (например, шифрование NTFS).
  • Если возможно, храните сами ключи в зашифрованном виде с помощью основного пароля. Обычно это означает ваше приложение. этот пароль потребуется вводить при запуске - бесполезно указывать его в параметре из скрипта, поскольку, если ваш жесткий диск взломан, вы должны предполагать, что и файл ключа, и скрипт могут быть просмотрены.
  • Если в имени пользователя нет необходимости находить учетную запись, зашифруйте как имя пользователя, так и пароль.
2 голосов
/ 04 июня 2009

По моему личному опыту, хранение личной информации и регистрационной информации в отдельных базах данных является наилучшей практикой в ​​этом случае. Причина, по которой происходит внедрение SQL, ограничена (если только проникший не знает внутреннюю структуру вашей базы данных) таблицей, к которой относятся данные, в отличие от предоставления доступа ко всему конгломерату данных.

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

0 голосов
/ 04 июня 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...