Предложения по хранению паролей в базе данных - PullRequest
0 голосов
/ 12 сентября 2009

Вот ситуация - она ​​немного отличается от других вопросов о базе данных / пароле на StackOverflow.com

У меня есть два набора пользователей. Одним из них являются «основные» пользователи. Остальные являются «вторичными» пользователями. У каждого есть логин / пароль к моему сайту (скажем, mysite.com - это не важно).

Справочная информация. Основные пользователи имеют доступ к третьему сайту (например, www.something.com/PrimaryUser1). Каждый вторичный пользователь «принадлежит» первичному пользователю и хочет получить доступ к подразделу этого другого сайта (например, www.something.com/PrimaryUser1/SecondaryUser1).

На mysite.com первичные пользователи должны предоставить свои учетные данные, которые они используют для доступа к www.something.com/PrimaryUser1, и они указывают, к каким «подчастям» получают доступ вторые пользователи по своему выбору.

Mysite.com помогает управлять дополнительным доступом вторичных пользователей к сайту основного пользователя. Вторичные пользователи не могут «видеть» пароль своего основного пользователя, но через мой сайт они могут получить доступ к «частям» другого сайта - но ТОЛЬКО к своей ограниченной части.

Грубо говоря, я реализую OAuth (или что-то в этом роде).

Вопрос здесь - как мне хранить учетные данные основного пользователя на другом сайте? Ключевым моментом здесь является то, что mysite.com использует эти учетные данные для предоставления доступа вторичным пользователям, поэтому он ДОЛЖЕН иметь возможность их прочитать. Однако я хочу сохранить его таким образом, чтобы основные пользователи были уверены, что я (как владелец сайта) не могу прочитать их учетные данные.

Полагаю, это больше вопрос теоретического подхода. Есть ли в мире криптографии что-нибудь, что может помочь мне в этом?


Текст добавлен:

Так как большинство людей полностью упускают вопрос, вот попытка №2 объяснить его.

PrimaryUser1 имеет имя пользователя / пароль для www.something.com/PrimaryUser1Site

Он хочет предоставить дополнительный доступ к папкам двум людям - SecondaryUser1 и SecondaryUser2 - www.something.com/PrimaryUser1Site/SecondaryUser1 и www.something.com/PrimaryUser1Site/SecondaryUser2

Mysite.com берет на себя управление этим пользователем, поэтому PrimaryUser1 отправляется туда и предоставляет свои учетные данные Mysite.com. MySite.com внутренне использует учетные данные, предоставленные PrimaryUser1, чтобы предоставить ограниченному доступу пользователей. Теперь SecondaryUser1 и SecondaryUser2 могут получить доступ к своим соответствующим папкам на сайте www.something.com/PrimaryUser1Site через MySite.com

СЕЙЧАС возникает вопрос, как мне хранить учетные данные, которые PrimaryUser1 предоставил?

Ответы [ 8 ]

4 голосов
/ 12 сентября 2009

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

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

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

А: Восьмое правило: всегда используйте HTTPS! Это не так безопасно, как большинство людей, но дает чувство безопасности вашим пользователям!


Поскольку вы добавили текст, я добавлю больше ответов.

Поскольку вы хотите, чтобы user1 предоставил временный доступ пользователю 2, вам понадобится дополнительная таблица пользователя. (Или разверните пользовательскую таблицу с помощью родительского идентификатора пользователя. Также добавьте временную метку, чтобы отслеживать возраст учетной записи. Пользователь 1 может создавать учетные данные, и это делается обычным способом. Просто сохраните хэш с объединенными именем пользователя и солью. В в этом случае используйте имя пользователя 1 в качестве дополнительной соли! Просто убедитесь, что вы отключите учетную запись пользователя 2, когда пользователь 1 выйдет из системы или когда пройдет определенное время. И разрешите пользователю 1 снова включить все учетные записи, чтобы он создал, чтобы они могли повторно использовать учетную запись вместо того, чтобы постоянно создавать новые.

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

Когда пользователь 1 входит в систему, он получает доступ к основному сайту. Когда он предоставляет доступ пользователю 2, пользователь 2 получает ограниченный набор ролей. Но это не имеет ничего общего с хранением имен пользователей или паролей. У вас просто есть идентификатор пользователя, который является членом определенных ролей или групп. Или нет, но они были бы недоступны.

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

1 голос
/ 12 сентября 2009

Это зависит от того, с какой аутентификацией согласуются ваш первичный сайт и вторичный сайт. Это форма аутентификации, HTTP Basic или HTTP Digest? Если это формы или базовые, то у вас нет выбора, вы должны сохранить пароль, поэтому ваш единственный выбор - зашифровать его. Вы не можете сохранить хэш пароля, так как вы должны представить открытый текст во время аутентификации для форм и HTTP Basic. Проблемы, возникающие при хранении зашифрованного пароля, связаны с неправильным использованием криптографии (т. Е. Вы не используете IV или соль или неправильно используете потоковый шифр), но, что более важно, у вас будет управление ключами проблемы (где хранить ключ, используемый для шифрования паролей и как получить к нему доступ из неинтерактивного сервиса / демона).

Если сторонний сайт принимает дайджест HTTP, то вам повезет, вы можете сохранить часть хеша HA1 (например, MD5 username:realm:password), поскольку вы можете создать Дайджест-ответ, начиная прямо с HA1.

Я не говорил о том, как пользователь предоставляет вторичные учетные данные (т. Е. Как вы получаете имя пользователя и пароль вторичного сайта в первую очередь), я предполагаю, что вы защитили защищенный канал (т. Е. HTTPS от клиента к первичному сайту). ).

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

0 голосов
/ 17 сентября 2009

Ты делаешь это слишком сложным. Вам нужно прекратить попытки смешивать аутентификацию и авторизацию.

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

Затем, когда вторичный пользователь хочет перейти на любой сайт в вашей ферме, он аутентифицирует себя только как себя - он никогда не выдавает себя за основного пользователя! И они имеют только те права, которые вы им предоставили, когда первичные пользователи дали им «вторичный» статус.

-

ОК, так как вы определили это решение в комментарии, подумайте:

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

Теперь, это совершенно не так, и я не анализировал это крипто, а проверил, что называется схемой секретного обмена . Сохраните «эффективный» или «реальный» пароль основного пользователя основного сайта в качестве общего секрета. Используйте соленый хеш пароля, предоставленный основным пользователем, как один секрет. Используйте соленый хеш пароля, предоставленный первым вторичным пользователем, в качестве другого секрета и т. Д. Для каждого дополнительного вторичного пользователя. Не храните соленые хэши! Просто храните соль и защищенный общий секрет.

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

0 голосов
/ 12 сентября 2009

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

Отметьте эту статью , если это китайский для вас.

0 голосов
/ 12 сентября 2009

Если вы хотите сохранить пароль самостоятельно, лучше всего использовать односторонний алгоритм хеширования, такой как MD5 или SHA-1. Преимущество этого подхода заключается в том, что you не может получить пароль из хешированного значения.

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

Редактировать

Вторичные пользователи должны иметь свои собственные пароли. Почему бы и нет?

0 голосов
/ 12 сентября 2009

Есть только один способ сделать это, и это, вероятно, слишком утомительно для пользователей.

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

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

0 голосов
/ 12 сентября 2009

есть лучший способ объяснить это: (

но если вы просто хотите знать, как безопасно хранить пароли, сделайте следующее:

имя пользователя: john, пароль: pass

key = '!! @ ijs09789 ** & *';

md5 (username.password.key);

при входе в систему просто проверьте, не равен ли md5 (username.password.key) = значению в базе данных - вы также можете использовать sha1 и любой другой метод шифрования.

http://us.php.net/md5 & http://us.php.net/sha1

0 голосов
/ 12 сентября 2009

Задумывались ли вы о принятии OpenID, как при переполнении стека? Таким образом, вы не несете ответственности за хранение паролей вообще.

...