Лучший способ обработки аутентификации учетных записей пользователей и паролей

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

Вопрос

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

Примеры:

  1. Хранение имени пользователя/пароля в базе данных.Это плохая идея, поскольку любой, у кого есть доступ к базе данных, может увидеть имя пользователя и пароль.И поэтому используйте его.

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

Как 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 и вообще не сохранять конфиденциальные пароли пользователей.Кто сказал, что это только для сайтов?

  1. Действительно очень плохая идея.Если база данных скомпрометирована, скомпрометированы все учетные записи.
  2. Хороший способ пойти.Если ваш алгоритм хеширования включает имя пользователя, замена хеша пароля на другой не сработает.

Unix хранит хеши в текстовом файле /etc/shadow, который доступен только привилегированным пользователям.Пароли шифруются солью.

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

Обычный подход — использовать второй вариант с электронной почтой:

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

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

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

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

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

Если «система» является общедоступным веб-сайтом РПХ может предоставить вам услуги входа/учетной записи пользователя для наиболее распространенных провайдеров, таких как OpenId, Facebook, Google и т. д.

Теперь, учитывая то, как вы формулируете свой вопрос, я думаю, что «система», о которой вы говорите, скорее всего, является внутренним корпоративным приложением на базе Windows/Linux.Тем не менее;для тех, кто ищет поставщиков логинов/учетных записей пользователей (как я делал до того, как наткнулся на RPX), это может подойти :)

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