Каков наилучший способ управления учетными записями пользователей в системе, не позволяя вашим сотрудникам, имеющим доступ к базе данных, иметь доступ к учетным записям.
Примеры:
Сохранение имени пользователя / пароля в базе данных. Это плохая идея, потому что любой, у кого есть доступ к базе данных, может видеть имя пользователя и пароль. И поэтому пользуйтесь им.
Хранение хеша имени пользователя / пароля. Это лучший метод, но доступ к учетной записи можно получить, заменив хэш пароля в базе данных хешем другой учетной записи, для которой вы знаете информацию об аутентификации. Затем, после того, как доступ будет предоставлен, верните его обратно в базу данных.
Как windows / * nix справляется с этим?

Вы можете сохранить соль для хешированного пароля в другой таблице, конечно, у каждого пользователя будет своя соль. Затем вы можете ограничить доступ к этой таблице.
Unix хранит хэши в текстовом файле / etc / shadow, который доступен только привилегированным пользователям. Пароли зашифрованы с солью.
Не могли бы вы поменять местами пароли двух пользователей, переместив хэши паролей в этом файле?
Брайан, нет, если алгоритм хеширования включает имя пользователя.
This is a better method, but the account can be accessed by replacing the password hash in the database with the hash of another account that you know the auth info for.
На самом деле нет никакого способа обойти это. Любой, у кого есть доступ на запись к файлу паролей, имеет полный контроль над компьютером.
Вы можете использовать openID и вообще не сохранять конфиденциальные пароли пользователей. Кто сказал, что это только для веб-сайтов?
Я бы выбрал 2, но немного соли. Какой-то псевдокод:
SetPassword(user, password)
salt = RandomString()
hash = Hashfunction(salt+password)
StoreInDatabase(user, salt, hash)
CheckPassword(user, password)
(salt, hash) = GetFromDatabase(user)
if Hashfunction(salt+password) == hash
return "Success"
else
return "Login Failed"
Важно использовать хорошо известную хеш-функцию (например, MD5 или SHA-1), реализованную в библиотеке. Не катите свой собственный и не пытайтесь реализовать его из книги просто не стоит рисковать ошибиться.
@Brian R. Bondy: Причина, по которой вы используете соль, состоит в том, чтобы усложнить атаку по словарю, злоумышленник не может хешировать словарь и попытаться проверить все пароли, вместо этого она должна взять соль + словарь и хешировать ее, что делает выставленные требования к хранению. Если у вас есть словарь из 1000 паролей через запятую, и вы их хешируете, вам нужно что-то вроде 16 КБ, но если вы добавите две случайные буквы, вы получите 62 * 62 * 16 КБ ≈ 62 МБ.
В противном случае вы могли бы использовать какой-нибудь Одноразовые пароли. Я слышал хорошие отзывы об OTPW, но не использовал его.
Есть ли польза от использования соли, если она также хранится в БД?
Согласен, но я бы посоветовал не использовать MD5, если доступен SHA-1. Уязвимости MD-5 хорошо задокументированы - SHA-1 «лучше».
+1 за крик о том, что вы не пишете свои собственные криптоалгоритмы :-)
Обычный подход - использовать второй вариант с электронной почтой:
Сохраните имя пользователя, хэш пароля и адрес электронной почты в базе данных.
Пользователи могут либо ввести свой пароль, либо сбросить его, в последнем случае генерируется случайный пароль, для пользователя создается новый хэш и пароль отправляется ему по электронной почте.
Обновлено: если база данных скомпрометирована, вы можете гарантировать только доступ к важной информации, вы больше не можете гарантировать безопасность своего приложения.
Зашешируйте имя пользователя и пароль вместе. Таким образом, если у двух пользователей одинаковый пароль, хэши все равно будут разными.
У Джеффа Этвуда есть несколько хороших постов о хешировании, если вы решите пойти по этому пути:
Это была распространенная проблема в UNIX много лет назад и была решена путем отделения компонентов идентификации пользователя (имя пользователя, UID, оболочка, полное имя и т. д.) От компонентов аутентификации (хэш пароля, соль хэша пароля). Компоненты идентичности могут быть глобально читаемыми (и фактически должны быть, если UID должны быть сопоставлены с именами пользователей), но компоненты аутентификации должен должны оставаться недоступными для пользователей. Чтобы аутентифицировать пользователя, имейте доверенную систему, которая будет принимать имя пользователя и пароль и будет возвращать простой результат «аутентифицирован» или «не аутентифицирован». Эта система должна быть единственным приложением, имеющим доступ к базе данных аутентификации, и должна ждать произвольное время (возможно, от 0,1 до 3 секунд), прежде чем ответить, чтобы избежать атак по времени.
Это не проблема для многих приложений, потому что получение доступа к базе данных, вероятно, является наиболее частой целью любого злоумышленника. Итак, если у них уже есть доступ к базе данных, почему они все еще хотят входить в приложение? :)
Верно для многих приложений. Не мой. Иногда в базе данных есть ссылки на файлы на диске. Доступ к базе данных не дает вам доступа к файлам на диске.
Если «система» является общедоступным веб-сайтом, RPX может предоставить вам услуги входа / учетной записи для наиболее распространенных поставщиков, таких как OpenId, Facebook, Google и т. д.
Теперь, учитывая то, как вы формулируете свой вопрос, я предполагаю, что «система», о которой вы говорите, скорее всего, является внутренним корпоративным приложением на основе Windows / Linux. Тем не менее; для тех, кто ищет в Google провайдеров логина / учетных записей (как я делал до того, как наткнулся на RPX), это может быть хорошим вариантом :)
Кто-то, имеющий доступ к БД, все же может иметь доступ к учетной записи. Им просто нужно временно переименовать имя пользователя.