Лучший способ обработки аутентификации учетных записей пользователей и паролей
-
09-06-2019 - |
Вопрос
Как лучше всего управлять учетными записями пользователей в системе, чтобы ваши сотрудники, имеющие доступ к базе данных, не имели доступа к учетным записям.
Примеры:
Хранение имени пользователя/пароля в базе данных.Это плохая идея, поскольку любой, у кого есть доступ к базе данных, может увидеть имя пользователя и пароль.И поэтому используйте его.
Хранение хеша имени пользователя/пароля.Это лучший метод, но доступ к учетной записи можно получить, заменив хеш пароля в базе данных хэшем другой учетной записи, для которой вы знаете информацию для аутентификации.Затем, после предоставления доступа, возвращаем его обратно в базу данных.
Как Windows/*nix справляется с этим?
Решение
Это была распространенная проблема в UNIX много лет назад, и она была решена путем отделения компонентов идентификации пользователя (имя пользователя, UID, оболочка, полное имя и т. д.) от компонентов аутентификации (хэш пароля, соль хэша пароля).Компоненты идентификации могут быть глобально доступны для чтения (и фактически должны быть таковыми, если UID должны быть сопоставлены с именами пользователей), но компоненты аутентификации должен оставаться недоступными для пользователей.Чтобы аутентифицировать пользователя, необходимо иметь доверенную систему, которая примет имя пользователя и пароль и вернет простой результат «аутентифицирован» или «не аутентифицирован».Эта система должна быть единственным приложением, имеющим доступ к базе данных аутентификации, и должна ждать случайное время (возможно, от 0,1 до 3 секунд), прежде чем ответить, чтобы избежать атак по времени.
Другие советы
Это лучший метод, но доступ к учетной записи можно получить, заменив хеш пароля в базе данных хэшем другой учетной записи, для которой вы знаете информацию для аутентификации.
На самом деле нет никакого способа обойти это.Любой, кто имеет доступ на запись в файл паролей, имеет полный контроль над компьютером.
Я бы взял 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), реализованную в библиотеке. Не создавайте свои собственные и не пытайтесь реализовать их из книги. просто не стоит рисковать ошибиться.
@ Брайан Р.Бонди:Причина, по которой вы используете соль, заключается в том, чтобы усложнить атаки по словарю, злоумышленник не может хешировать словарь и попытаться использовать все пароли, вместо этого ему приходится взять соль + словарь и хэшировать его, что приводит к расширению требований к хранилищу.Если у вас есть словарь из 1000 наиболее распространенных паролей и вы их хешируете, вам понадобится что-то вроде 16 КБ, но если вы добавите две случайные буквы, вы получите 62*62*16 КБ ≈ 62 МБ.
В противном случае вы могли бы использовать какой-то Одноразовые пароли Я слышал хорошие отзывы об OTPW, но не использовал его.
У Джеффа Этвуда есть несколько хороших статей о хешировании, если вы решите пойти по этому пути:
Вы можете использовать openID и вообще не сохранять конфиденциальные пароли пользователей.Кто сказал, что это только для сайтов?
- Действительно очень плохая идея.Если база данных скомпрометирована, скомпрометированы все учетные записи.
- Хороший способ пойти.Если ваш алгоритм хеширования включает имя пользователя, замена хеша пароля на другой не сработает.
Unix хранит хеши в текстовом файле /etc/shadow, который доступен только привилегированным пользователям.Пароли шифруются солью.
Вы можете хранить соль для хешированного пароля в другой таблице, конечно, у каждого пользователя будет своя соль.Затем вы можете ограничить доступ к этой таблице.
Обычный подход — использовать второй вариант с электронной почтой:
Сохраните имя пользователя, хэш пароля и адрес электронной почты в базе данных.
Пользователи могут либо ввести свой пароль, либо сбросить его. В последнем случае генерируется случайный пароль, для пользователя создается новый хэш, и пароль отправляется ему по электронной почте.
Редактировать:Если база данных скомпрометирована, вы можете только гарантировать, что доступ к важной информации невозможен, вы больше не сможете обеспечить безопасность своего приложения.
Хешируйте имя пользователя и пароль вместе.Таким образом, если у двух пользователей одинаковый пароль, хеши все равно будут разными.
Для многих приложений это не является проблемой, поскольку получение доступа к базе данных, вероятно, является наиболее распространенной целью любого злоумышленника.Итак, если у них уже есть доступ к базе данных, зачем им еще входить в приложение?:)
Если «система» является общедоступным веб-сайтом РПХ может предоставить вам услуги входа/учетной записи пользователя для наиболее распространенных провайдеров, таких как OpenId, Facebook, Google и т. д.
Теперь, учитывая то, как вы формулируете свой вопрос, я думаю, что «система», о которой вы говорите, скорее всего, является внутренним корпоративным приложением на базе Windows/Linux.Тем не менее;для тех, кто ищет поставщиков логинов/учетных записей пользователей (как я делал до того, как наткнулся на RPX), это может подойти :)