Как хранить имена пользователей и пароли для автоматической аутентификации? - PullRequest
1 голос
/ 08 апреля 2011

В организации, в которой я работаю, есть несколько разных веб-сайтов, которые они используют ежедневно.Меня попросили разработать веб-приложение (с использованием ASP.NET), которое может получать / синтезировать информацию из них и отображать ее в одном месте.К сожалению, один из веб-сайтов не поддерживает OAuth или что-либо подобное, поэтому мне нужно сохранить их учетные данные для входа в базу данных.

Первой моей мыслью было использование их учетных данных для моего сайта в качестве ключа для шифрования их учетных данных.для удаленного сайта.Например: Боб входит на мой сайт с паролем hunter2.Используя этот пароль, я расшифровываю учетные данные Боба для www.example.com и захожу как Боб.Поскольку мне не нужен доступ к example.com, если Боб не находится на моем сайте, я могу отказаться от расшифрованных учетных данных, как только он это сделает.

Мое предположение, что простое использование hunter2 (или любого другого пароля Боба) не являетсядостаточно того, что есть «стандартный» способ, который я не смог найти в Google или в переполнении стека.

Ответы [ 3 ]

1 голос
/ 09 апреля 2011

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

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

Не используйте действительный пароль пользователя в качестве ключа к функции шифрования.

Подумайте, что было бы возможно, если бы вы это сделали: что если злоумышленнику удастся загрузить всю вашу таблицу users с зашифрованными паролями example.com ? Все мы знаем, что выбранные пользователем пароли легко угадать. Что помешает злоумышленнику неоднократно расшифровывать зашифрованный пароль example.com , пытаясь использовать 40 миллионов часто используемых паролей в качестве ключа, отбрасывая любой результат, не похожий на пароль (который есть, расшифрованный результат не появляется в списке слов)? AES предназначен для быстрого . Хотя это не сравнение между яблоками и яблоками, ощущение скорости AES следует придавать, если учесть, что зашифрованная версия вышеупомянутого списка слов 500 Мб может быть расшифрована примерно за одну секунду на современном оборудовании. Хуже того, злоумышленник получит не только пароль example.com , но и ключ, используемый для шифрования, или, другими словами, главный пароль пользователя!

В двух словах, именно поэтому вам необходимо использовать функцию получения ключа (KDF). KDF идеально защитит вас тремя способами:

  1. Требуется нетривиальное количество времени для вычисления каждого ключа. Пользователь может подождать одну секунду, пока сервер превратит свой пароль в ключ. Злоумышленник может быть менее склонен ждать 40 000 000 секунд - см. Анализ ниже.
  2. Соль пароль. Без соли злоумышленник может перебить всю таблицу пользователей за один проход, не говоря уже о пространственно-временном обмене .
  3. Запретить восстановление мастер-пароля, даже если злоумышленник восстановит ключ шифрования.

Один из таких KDF, который обеспечивает все три: PBKDF2 . Для удобства есть реализация , встроенная в .NET:

public static byte[] DeriveKey(int keyBitSize, string password, byte[] salt) {
    const int iterations = 1<<12; // Once set, any change will break decryption.
    using (var kdf = new Rfc2898DeriveBytes(password, salt, iterations)) {
        return kdf.GetBytes(keyBitSize);
    }
}

Анализ

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

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

0 голосов
/ 09 апреля 2011

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

Если вы используете собственный пароль пользователя для шифрования, вы уменьшаете надежность всех его вторичных паролей до прочности основного.Это, вероятно, плохо, так как а) пользовательские пароли, как известно, уже слабы (я знаю, почему мы вообще беспокоимся об этом?) И б) даже при использовании самых надежных паролей он все равно не будет соответствовать прочности абсолютно случайных256-битный ключ AES.

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

0 голосов
/ 08 апреля 2011

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

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

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

Теперь в ненадежной среде кто-то может получить мои двоичные файлы, определить их ключ и получить все пароли. Это было бы плохо. Но в корпоративной сети, если они это сделали, они должны прийти и работать на меня.

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