Рекомендации по обеспечению безопасности имени пользователя / пароля между клиентами и сервером - PullRequest
8 голосов
/ 10 августа 2010

Получил приложение (C # WPF), которому нужно «позвонить домой» и получить обновленную информацию с домашнего сервера.Теоретически могут существовать тысячи клиентов, которым необходимо общаться через общедоступный Интернет.

Каждый пользователь сначала регистрируется с именем пользователя и паролем.Затем, когда приложение запускается, оно время от времени будет звонить домой для получения информации о новых версиях, новостей, комментариев, сообщений для пользователя и других специфических вещей приложения.Это не будет приложение для «всех», но, как уже упоминалось, пользователей может быть довольно много, поэтому безопасность является приоритетом.Я хочу, чтобы это было очень, очень трудно взломать, но если это невозможно, я тоже пойду.:)

Существует только несколько основных операций, которые необходимо поддерживать;

  • Первоначальная регистрация нового пользователя
  • Проверка имени пользователя и пароля
  • A "Что нового с [TIMESTAMP]?"операция
  • Клиент, публикующий комментарии, сообщения или другой разрешенный пользователем контент

На стороне сервера все будет на сервере Win2008 с IIS7.У меня почти нет знаний, необходимых мне в WCF, чтобы реализовать это в то время, которое у меня есть для проекта, поэтому я буду заниматься магией ASP.NET MVC 2 с файлами XML туда и обратно.Если все, что у вас есть, это молоток.

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

Я понимаю, что это в определенной степени будет вопросом мнения, но я также считаю, что должна быть возможность получить какую-то лучшую практикугде я могу спать по ночам, не беспокоясь о клиентском <-> взаимодействии с сервером и о том, что у пользователей есть учетные записи и т.д.Или в зашифрованном виде, чтобы получить его обратно?

Я думаю, HTTPS между клиентом и сервером для хорошего уровня безопасности по умолчанию.Плохая идея?Нет? Нужно ли вообще "входить" с этой моделью?Нужно ли отправлять комбинацию имени пользователя и пароля при каждом запросе? Если я выберу https, достаточно ли это безопасно в этот момент?Или я все еще должен зашифровать некоторые компоненты аутентификации? Есть ли точка на сервере, предоставляющем какой-то токен шифрования, который можно использовать как соль (я не очень знаком с терминологией здесь) для дальнейшего шифрования имени пользователя / пароля? По сути, как я могу защитить эту систему до такой степени, чтобы никто за пределами клиентских или серверных машин не мог украсть информацию об учетной записи?Я, конечно, понимаю, что если плохие парни завладеют надлежащим файлом конфигурации, то эта учетная запись будет взломана.Эта система, конечно, никогда не позволит выполнять какие-либо критические операции с использованием этой связи, все, что будет происходить на сервере;Тем не менее, я считаю взлом аккаунта очень-очень плохой вещью, которую я должен принять все возможные меры, чтобы избежать.

Есть хорошие идеи?

Спасибо!

Ответы [ 3 ]

5 голосов
/ 10 августа 2010

У вас есть две различные проблемы: аутентификация зарегистрированного пользователя и подготовка новой учетной записи пользователя.

Аутентификация пользователя

Это простая часть.У вас есть несколько вариантов:

  • HTTP-аутентификация ( basic или digest ).Basic - это шутка, поэтому в качестве серьезной альтернативы он оставляет только Digest.
  • HTTP-аутентификация NTLM / Kerberos (иначе говоря, встроенная аутентификация Windows) является пуленепробиваемой, если ваши клиенты присоединяются к домену NT (маловероятно).
  • SSL / TLS Взаимная аутентификация
  • HTTP-аутентификация по формам.Не стоит упоминать.
  • Базовая проверка подлинности или проверка подлинности с помощью форм по безопасному каналу ( HTTPS )

Таким образом, остаются реальные опции: дайджест, взаимная защита SSL или базовые / формыпо зашифрованному каналу.

Дайджест HTTP очень легко реализовать на стороне клиента, просто добавьте имя пользователя / пароль к CredentialCache, используемому с WebRequest и все готово.Повторно используйте экземпляр CredentialCache между вызовами, чтобы воспользоваться преимуществами предварительной аутентификации.К сожалению, на стороне сервера все не так радужно: дайджест-проверка подлинности поддерживается должным образом только при интеграции с AD, см. Настройка дайджест-проверки подлинности .

Взаимная проверка подлинности SSL / TLS поддерживается как клиентом, так и сервером, но, опять же, серверная сторона действительно поддерживает его только при интеграции с AD, а не в режиме реального времени (см. Настройка аутентификации сопоставления сертификата клиента ).

Этопочему я считаю, что единственными реалистичными вариантами для приложения, которое не предназначено для использования по VPN в корпоративной среде, является использование базовой аутентификации или проверки подлинности с помощью форм по безопасному каналу (HTTPS).Для Basic вы должны представить пароль в виде обычного текста и то же самое для форм (в его обычном неизмененном воплощении), поэтому клиент должен иметь доступ к паролю в виде открытого текста, и то же самое относится и к серверу.Один из способов хеширования не сработает, вам нужно правильное шифрование безопасного хранения.

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

Хранениепароль: Для Basic / Digest / Forms клиент не хранит пароль, так как пароль фактически предоставляется пользователем.Самое большее, пароль может быть сохранен, чтобы избежать повторного ввода, и это должно быть сделано, как любой специфический для пользователя секрет, хранящийся на клиенте, зашифрованный с помощью DPAPI через класс ProtectedData .На стороне сервера, если используется пользовательская таблица, пароли должны храниться как односторонний хэш.Для Basic и Form подойдет любая хеш-схема (желательно соленая).Но для дайджеста хэш должен быть хешем HA1 из схемы дайджеста: md5(username:realm:password), чтобы сервер мог завершить квитирование аутентификации.Хотя для этого требуется довольно инвазивное переписывание стандартных провайдеров членства, которые поставляются с ASP, это все еще мой рекомендуемый способ.

Подготовка пользователя

Это немногохитрее, потому что это предполагает установление первоначального доверия.Если вы просмотрите все схемы, упомянутые выше, вы увидите, что ни одна, кроме Basic / Forms поверх HTTPS, не может сделать это внутриполосно: любое другое решение требует первоначального развертывания учетной записи пользователя, настроенной внеполосными средствами (где внеполосные ссылки относятся к используемой схеме).Взаимный SSL требует предоставления сертификатов, NTLM / Kerberos требует подготовки пользователей AD, Digest требует предоставления пароля пользователя.Для Basic / Forms и Digest существует удобное «внеполосное» решение: безопасный канал HTTPS, на который отправляется форма для создания учетной записи.Для сертификатов SSL / TLS и для AD все сложнее.

OpenID / OAuth

Совершенно другой подход заключается в делегировании аутентификации. Используйте OpenID с провайдерами, такими как Google или Yahoo, и OAuth с провайдерами, такими как Facebook или Twitter. Это феноменально хорошо работает с веб-приложениями (сама StackOverflow использует такую ​​схему, как вы могли заметить, OpenID, один год спустя ). Существуют библиотеки и поставщики интеграции, которые действительно делают это так просто, как 3 клика и одна строка кода, например JanRain .

Единственная проблема с OpenID и OpenAuth - это интерактивная схема. Это работает только в том случае, если пользователь активно участвует в процессе входа в систему / аутентификации и, следовательно, устраняет все автоматизированные решения. Если ваше приложение выполняет какие-либо фоновые операции (например, работает как служба) или использует идентификатор приложения для «телефона-дома» без участия пользователя, тогда OpenID / OAuth не работают.

2 голосов
/ 10 августа 2010

Нет простого ответа на такой широкий вопрос, как этот.Существует множество видов угроз, с которыми может столкнуться ваше приложение, - то, что обычно нужно делать, называется моделирование угроз , состоящее из:

  • выявление уязвимостей
  • выявление векторов атаки
  • выявление возможных контрмер

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

Несмотря на то, что существуют рекомендации по обеспечению безопасности, вы не можете просто следовать рецепту защиты системы.

Хотя в целом вы упоминаетенекоторые разумные контрмеры для защиты приложения (хеширование пароля, HTTPS) дьявол кроется в деталях.Иногда вам приходится учитывать такие сценарии, как:

  • повторные атаки (где трафик сообщений записывается и воспроизводится)
  • атаки отказа в обслуживании (где ваш сервер засыпан некорректными или недействительными сообщениями в попытке его перегрузить)
  • человек посередине (атаки, при которых злоумышленник перехватывает или изменяет сообщения в пути)

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

Microsoft опубликовала нечто под названием Life Development Lifecycle (SDL) , который вы, возможно, захотите изучить.В MSDN есть также целый раздел Security Engineering , в котором есть много предыстории и рекомендаций по этой теме.

1 голос
/ 10 августа 2010

Я думаю, что это ответит только на часть «шифрования» вашего вопроса, но сегодня утром я прочитал отличную статью о шифровании в Silverlight и .NET, которую можно использовать для защиты конфиденциальной информации:

Вот часть содержимого статьи:

Первый шаг, конечно, - найти достаточнонадежный протокол шифрования, который может быть реализован как в Silverlight, так и в .NET и полностью совместим между обеими средами выполнения.Я собираюсь пойти на шифрование AES.AES расшифровывается как «Advanced Encryption Standard».Этот стандарт широко используется и одобрен правительством США и стандартными органами.

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