Asp доступ к клиентским сертификатам с помощью asp


Содержание

Asp доступ к клиентским сертификатам с помощью asp

Для программирования безопасности Windows Communication Foundation (WCF) обычно используются цифровые сертификаты X.509, с помощью которых выполняется проверка подлинности клиентов и серверов, шифрование, а сообщения подписываются цифровой подписью. В этом разделе содержится краткое описание функций для работы с цифровыми сертификатами X.509 и порядка использования этих функций в WCF. Кроме того, этот раздел включает ссылки на другие разделы с более подробным объяснением основных понятий и порядка выполнения общих задач с использованием WCF и сертификатов.

Вкратце, цифровой сертификат является частью ключевого индикатора производительности (PKI), представляющей собой систему цифровых сертификатов, центров сертификации и других центров регистрации, которые используются для проверки подлинности каждой стороны, участвующей в электронной транзакции, посредством использования асимметричного шифрования. Сертификаты выдаются центрами сертификации. Каждый сертификат имеет набор полей, в которых содержатся такие данные, как субъект (сущность, которой выдается сертификат), срок действия (период времени, в течение которого сертификат является действительным), издатель (лицо, выдавшее сертификат) и открытый ключ. В WCF каждое из этих свойств обрабатывается как утверждение Claim, и каждое утверждение затем подразделяется на два типа: удостоверение и право. Дополнительные сведения о о сертификатах X.509 см. в разделе Сертификаты с открытым ключом X.509Дополнительные сведения о об утверждении и авторизации в WCF см. в разделе Управление утверждениями и авторизацией с помощью модели удостоверения. Дополнительные сведения о о реализации ключевого индикатора производительности см. в разделе Windows Server 2008 R2 — службы сертификатов.

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

Сертификаты должны выдаваться центром сертификации, который обычно является сторонним издателем сертификатов. Центр сертификации входит в состав домена Windows, чтобы можно было использовать его для выдачи сертификатов компьютерам домена.

При работе с сертификатами зачастую необходимо просматривать их и проверять определенные свойства. Это легко выполняется с помощью консоли управления (MMC). Дополнительные сведения см. в разделе . Как просматривать сертификаты с помощью оснастки консоли MMC.

Сертификаты хранятся в хранилищах. Существует два основных хранилища, которые подразделяются на вложенные хранилища. Администратор компьютера может просматривать оба основных хранилища с помощью средства MMC. Пользователи, не являющиеся администраторами, могут просматривать только хранилище текущего пользователя.

Хранилище локального компьютера . Содержит сертификаты, доступ к которым осуществляется выполняющимися на компьютере процессами, такими как ASP.NET. Это расположение используется для хранения сертификатов, удостоверяющих подлинность сервера для клиентов.

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

Эти два хранилища подразделяются на вложенные хранилища. Ниже представлены наиболее важные вложенные хранилища, используемые при программировании с WCF.

Доверенные корневые центры сертификации . Сертификаты в этом хранилище могут быть использованы для создания цепочки сертификатов, которая может вести обратно к центру сертификации в этом хранилище.

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

Личное Это хранилище используется для хранения сертификатов, связанных с пользователем компьютера. Обычно в этом хранилище хранятся сертификаты, выданные одним из центров сертификации, сертификаты которых находятся в хранилище «Доверенные корневые центры сертификации». С другой стороны, сертификат, находящийся в этом хранилище, может быть самостоятельно выданным, и ему будет доверять приложение.

Дополнительные сведения о хранилищах сертификатов см. в разделе Хранилища сертификатов.

Выбор расположения для хранения сертификата зависит от режима и места выполнения клиента или службы. Действуют следующие общие правила.

Если служба WCF в службе Windows, используйте хранилище локального компьютера. Обратите внимание, что для установки сертификатов в хранилище локального компьютера требуются привилегии администратора.

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

Хранилища защищаются с помощью списков управления доступом (ACL) аналогично папкам на компьютере. При создании службы, размещаемой в IIS, процесс ASP.NET выполняется от имени учетной записи ASP.NET. Эта учетная запись должна иметь доступ к хранилищу, в котором содержатся используемые службой сертификаты. Каждое основное хранилище защищается с помощью списка управления доступом по умолчанию, однако списки можно изменять. При создании отдельной роли для доступа к хранилищу необходимо предоставить ей разрешение на доступ. О том, как изменить список доступа с помощью программы WinHttpCertConfig.exe, см. в разделе Практическое руководство. Создание временных сертификатов для использования во время разработки. Дополнительные сведения о использовании сертификатов клиента в службах IIS см. в разделе Как вызвать веб-службу с использованием клиентского сертификата для аутентификации в веб-приложении ASP.NET.

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

Цифровые сертификаты используются для удостоверения подлинности сущности на основе этой иерархии, которая также называется цепочкой сертификатов. Цепочку любого сертификата вы можете просмотреть с помощью оснастки MMC, дважды щелкнув сертификат и выбрав вкладку Путь сертификата. Дополнительные сведения о об импорте цепочек сертификатов для центра сертификации см. в разделе Как указать цепочку сертификатов центра сертификации, используемую для проверки сигнатур (WCF).

Любой издатель может быть сделан доверенным корневым центром; для этого необходимо поместить сертификат издателя в хранилище сертификатов доверенных корневых центров.

При создании новой службы пользователь может использовать сертификат, который был выдан центром сертификации, отличным от доверенного, или сертификат издателя может отсутствовать в хранилище «Доверенные корневые центры сертификации». Предусмотрена возможность временного отключения механизма, проверяющего цепочку сертификатов для заданного сертификата; эта возможность должна использоваться только в процессе разработки. Чтобы отключить данный механизм, задайте для свойства CertificateValidationMode значение PeerTrust или PeerOrChainTrust. Эти режимы определяют, что сертификат может быть либо самостоятельно выданным (доверие одноранговой группы), либо являться частью цепочки доверия. Указанное свойство можно задать для любого из следующих классов.

Средства безопасности ASP.NET. Аутентификация

Давайте теперь перейдём к описанию процесса аутентификации непосредственно в рамках среды ASP.NET, где для вашего выбора предоставлены 3 вида аутентификации:

* Аутентификация Windows
* Формой
* Паспортом

Аутентификация Windows:

Как и следует из названия, этот метод основывается на использовании учётных записей Windows. Такой метод уместен, если вы создаёте приложение для локальной сети, и все действующие учётные записи и группы хранятся на заранее определённом домене. При этом нужно быть очень осторожными, назначая права доступа пользователям, поскольку вы одновременно задаёте и права для работы в Windows. Для того, чтобы настроить ASP.NET на работу в режиме Windows аутентификации необходимо изменить файл настройки Web-проекта Web.config или при необходимости конфигурационный файл всего сервера, расположенный по адресу WINDOWS_FOLDERMicrosoft.NET

Framework.NET versionCONFIGMachine.config. В нашем примере мы будем работать исключительно с файлом проекта – Web.config, в котором вам нужно найти раздел authentication и присвоить его атрибуту mode значение Windows:

Теперь можно приступить непосредственно к программированию и реализации аутентификации на основе Windows. В помощь вам класс WindowsIdentity, который служит специально для работы с аутентификацией Windows. Вообще, для аутентификации, базирующейся на Windows, существуют два основных класса, предоставляемых .NET Framework:

* GenericIdentity – только реализует интерфейс IIdentity и не относится к какому-то определённому типу аутентификации
* WindowsIdentity – также является реализацией интерфейса IIdentity, но плюс ещё и включает методы, характерные только для аутентификации на основе Windows

Имя пользователя и группы хранятся в объекте WindowsIdentity в следующем формате: DOMAINUserName и DOMAINGroup соответственно. Исключение составляют лишь встроенные группы, например группа Administrators, для обращения к ней можно использовать строку подключения через WindowsIdentity: BUILTINAdministrators. Или же можно задать встроенную группу из перечисления System.Security.Principal.WindowsBuiltInRole.

Из рис. 1 видно, что объект WindowsIdentity позволяет получить имя пользователя; определить тип аутентификации; установить, была ли аутентификация проведена анонимно; также можно узнать, прошёл пользователь аутентификацию или нет, гость он или системный пользователь.

Рис. 1 – Объект WindowsIdentity

Поскольку в приложениях ASP.NET для обращения к объекту WindowsIdentity нужно будет выстроить следующую цепочку:

HttpContext.Current.User.Identity, то вы сможете также определить, к какой роли принадлежит текущий пользователь. Это можно достичь благодаря тому, что свойство User в этой цепочке реализует интерфейс Iprincipal, который позволяет определить принадлежность пользователя к определённой роли путём вызова функции IsInRole, имеющей следующий синтаксис:

Но давайте ненадолго отойдём от голой теории и попробуем реализовать практический пример. Для этого создайте новый проект ASP.NET Web Application и введите следующий код:
Default.aspx:

Если был выбран режим аутентификации Windows и настройки IIS не вызвали никаких конфликтных ситуаций, то вы получите соответствующую информацию о своём текущем пользователе. Если же поле имени пользователя и типа аутентификации оказались пустыми, то вам нужно просто настроить IIS, для этого выполните следующие действия:

1. Откройте IIS и найдите виртуальный каталог с этим приложением
2. Откройте окно свойств для этого каталога и перейдите во вкладку Безопасность каталога. В рамке Анонимный доступ и проверка подлинности нажмите кнопку Изменить…
3. В появившемся окне (рис. 2) снимите флажок Анонимный доступ

Рис. 2 – Настройка IIS


На этом мы закончим рассмотрение аутентификации на основе Windows и перейдём к аутентификации формой.

Аутентификация формой:

Аутентификация формой или, как её ещё называют аутентификация на основе Cookie-файлов, имеет ряд преимуществ над аутентификацией Windows.

* Во-первых, вы имеете возможность самому определить на свой вкус и цвет или на вкус и цвет пользователя внешний вид формы регистрации вместо однотипного окна регистрации Windows.
* Во-вторых, вы полностью контролируете вводимую информацию
* Сведения о пользователях теперь может храниться не только в SAM или Active Directory, но и в любом другом хранилище, в частности: база данных, каталог LDAP, XML-файлы или же обычный текстовый файл.
* Отпадает необходимость связывать политику безопасности сервера с политикой Web-приложения, поскольку, как уже было ранее сказано, все сведения о пользователях можно вынести в отдельное хранилище данных без каких-либо пересечений с учётными записями ОС.

Часть 2. Установка SSL-сертификатов для клиента и сервера и ограничение доступа к Web-сайту на стороне сервера

Серия контента:

Этот контент является частью # из серии # статей: SSL-сертификаты Web-сайтов и их применение

Этот контент является частью серии: SSL-сертификаты Web-сайтов и их применение

Следите за выходом новых статей этой серии.

Наиболее распространённой областью применения SSL-сертификатов является защита HTTP-трафика, для чего сертификат устанавливается на Web-сервер и используется для шифрования трафика между сервером и клиентом. Корпоративная почта и системы групповой работы, системы хранения документов и всевозможные Web-приложения — все они нуждаются в защите HTTP-трафика.

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

Установка серверного сертификата

Часто используемые сокращения.

  • SSL — уровень защищенных сокетов (secure socket layer);
  • CA — удостоверяющий центр (center of authority);
  • CSR — запрос на сертификацию (certificate signing request);
  • CRL — список отозванных сертификатов (certificate revocation list);
  • PKCS — криптографические стандарты с открытым ключом (public-key cryptography standards);
  • CN — общие данные (common name).

Для того, чтобы к Web-сайту можно было обращаться по протоколу HTTPS, на нем должен быть установлен собственный сертификат. «Собственный» означает, что имя сайта, используемое клиентами для обращения к сайту, совпадает с именем, указанным в поле CN сертификата. Однако, так как по требованиям протокола SSL комбинация «адрес:порт» должна быть уникальной, то установить несколько различных виртуальных серверов (с различными сертификатами) на один порт 443 не получится, и для каждого сервера потребуется выделить отдельный порт и указать его при описании данного сервера.

Процесс создания SSL-сертификата для сервера описывался в предыдущей части статьи. Поэтому предполагается, что серверный сертификат уже создан и подписан в корпоративном СА, а также имеются файлы myfile.key и myfile.crt, соответствующие ключу и сертификату сайта. Но до того, как клиенты Web-сайта смогут начать ими пользоваться, эти файлы потребуется подключить к Web-серверу (в рамках данной статьи используется Wеб-сервер Apache) через конфигурационный файл виртуального сервера (или корневого сайта) как показано в листинге 1:

Листинг 1. Подключение SSL-сертификатов

В листинге 1 приведены только параметры (директивы конфигурации Apache), относящиеся к SSL-сертификатам, поэтому для полноценной конфигурации потребуется указать и другие параметры. Указанные директивы записываются в блоке (для виртуального сервера) или в конфигурационном файле корневого сервера (для стандартного Web-сервера).

В данном примере выполняется включение SSL (1-ая строка), на 2-ой строке происходит отключение слабой и небезопасной версии 2.0 протокола SSL. Затем на 3-ей строке устанавливаются параметры защищенного соединения, которые могут использоваться (какой набор параметров будет выбран, зависит еще и от подключающегося клиента). На строках 4 и 5 указываются SSLCertificateFile и SSLCertificateKeyFile – пути к файлу c SSL-сертификатом и к файлу с ключом сертификата.

Для нормальной работы SSL необходимо, чтобы имя сервера, прописанное в директиве ServerName, совпадало с именем, указанным для поля CN в процессе создания сертификата. Если это правило не выполняется, то при обращении к сайту Web-браузер будет постоянно отображать страницу с предупреждением.

Важное примечание: проверяется именно директива ServerName, а не директива ServerAlias. Если для сервера необходимо указать несколько имен, то их можно прописать в директиве ServerAlias.

Установка сертификата в Web-браузер пользователя

Тем не менее при первой попытке войти на сайт, где установлен SSL-сертификат, подписанный корпоративным СА, все равно возникнет ошибка, так как Web-браузер будет утверждать, что возникла критическая ситуация и это поддельный сертификат. В Web-браузере Google Chrome будет отображена страница красного цвета во весь экран, а в Mozilla Firefox – желтого, при этом обе страницы будут предупреждать пользователя, что произошел критический сбой в системе безопасности, как показано на рисунках 1 и 2.

Рисунок 1. Отображение неизвестного сертификата в Google Chrome
Рисунок 2. Отображение неизвестного сертификата в Mozilla Firefox

Web-браузеры выводят сообщения, изображенные на рисунках, так как не могут проверить, какая организация подписала данный сертификат. Как уже упоминалось в прошлой части, система CA – иерархическая, и сертификаты корневых СА распространяются вместе с Web-браузерами. В Google Chrome используется хранилище сертификатов Windows, и его список корневых сертификатов может измениться после установки пакета с обновлениями от Microsoft, а в Mozilla Firefox используется собственное хранилище сертификатов.

Поскольку данный сертификат подписан внутри самой организации, то её корневой сертификат у Web-браузера, конечно, отсутствует, и он считает, что произошла ошибка. Чтобы исправить эту ошибку, достаточно просто распространить на все компьютеры в локальной сети сертификат корпоративного СА (файл caserv.crt) ещё до того момента, как пользователи начнут обращаться к корпоративным Web-ресурсам по протоколу HTTPS. Этот сертификат потребуется установить в системное хранилище Windows и в хранилище Firefox (а если используется еще и Web-браузер Opera, то и в его собственное хранилище).

Процесс установки сертификата не представляет особой сложности, однако система несколько раз уточнит: действительно ли можно доверять этому издателю сертификатов. Также необходимо обратить внимание, куда именно будет установлен сертификат: он должен быть установлен в «Доверенные Корневые Центры Сертификации», а не в какую-либо другую группу.

Преобразование SSL-сертификата из одного формата в другой

Установка корневого сертификата на мобильное устройство (например, смартфон Nokia N95 8G) требует значительно больше усилий, так как смартфон не понимает текстовых сертификатов (формат PEM). Поэтому в данном разделе рассматривается процесс перекодирования сертификата из одного формата в другой.

Существуют два стандартных формата для хранения сертификатов — PEM (текстовый) и DER (двоичный). С точки зрения содержания они не отличаются друг от друга, но текстовый формат разработан так, чтобы его можно было просматривать в текстовых редакторах и без проблем пересылать по почте. Отличие между форматами состоит в степени их поддержки различными устройствами, так как формат PEM поддерживается далеко не всеми устройствами. Поэтому для установки корневого сертификата СА на устройство, которое не поддерживает формат PEM, его потребуется предварительно перекодировать.

Перекодирование сертификата из формата PEM в формат DER выполняется следующей командой:

Расширение файла (.cer) – это стандартное расширение для сертификатов формата DER. Этот формат поддерживается большим числом оборудований, в частности, упомянутым выше смартфоном Nokia N95 8G. Обратное преобразование из формата DER в формат PEM выполняется сходным образом:

Для обратного преобразования в команде достаточно просто поменять порядок аргументов, но полученный таким образом PEM-файл не будет содержать текстовой части (содержимое сертификата, пригодное для просмотра человеком), поэтому для создания сертификата с заполненной текстовой частью используется другая команда:

Если же, наоборот, необходимо удалить из сертификата текстовую часть, то используется следующая команда:

Сертификат корпоративного СА, перекодированный в формат DER, переносится на смартфон и устанавливается способом, специфичным для конкретного мобильного устройства.

Установка SSL-соединения с Web-сайтом

После того, как сертификат корпоративного СА установлен в качестве корневого, Web-браузеры распознают сертификаты, подписанные им, и больше не выводят страниц с предупреждениями, а сразу устанавливают соединение с запрошенным ресурсом, как показано ниже.


Рисунок 3. Установленное SSL-cоединение в Google Chrome
Рисунок 4. Установленное SSL-cоединение в Mozilla Firefox

При выполнении подключения к Web-сайту с установленным SSL-сертификатом дополнительно могут проверяться следующие параметры: дата начала и окончания срока действия сертификата. Если дата начала срока действия еще не наступила или наоборот, дата окончания срока действия уже прошла, то сертификат, независимо от наличия установленного корневого сертификата CA, будет объявлен ошибочным.

Также может быть проверено, не отозван ли данный сертификат. Как было упомянуто в предыдущей статье, система должна иметь возможность блокировки сертификатов, которые были выданы людям, на данный момент покинувшим организацию. Поэтому в сертификат можно добавить параметры, которые будут распознаваться Web-браузерами. На основании полученной информации Web-браузер сможет загрузить с указанного адреса CRL и проверить, не входит ли сертификат, используемый для подключения, в список отозванных. Если этот сертификат присутствует в списке отозванных, то соединение будет заблокировано.

Важное примечание: ссылка на CRL должна указываться и в параметре CRLDistributionPoint (как определено в новой версии стандарта), так и в параметре nsCaRevocationList — именно этот параметр считывается многими Web-браузерами, и при его отсутствии возникают сообщения об отсутствующем списке CRL и т.д.

Ограничение возможности подключения для нежелательных клиентов

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

Листинг 2. Добавление ограничений на подключение клиентов

Параметры SSLCertificateChainFile и SSLCACertificateFile задают сертификат корпоративного СА, параметр SSLCARevocationFile определяет путь к CRL, а параметр SSLVerifyClient активирует проверку клиентского сертификата. В этом примере вводится самое простое ограничение: к сайту смогут подключиться только те пользователи, у которых на компьютерах установлен клиентский сертификат, подписанный корпоративным СА. При этом никаких дополнительных проверок выполняться не будет, если на клиентском компьютере, осуществляющем подключение к серверу, отсутствует клиентский сертификат, то в установке подключения будет отказано, как показано ниже.

Рисунок 5. Страница с сообщением об отказе в подключении в Google Chrome
Рисунок 6. Страница с сообщением об отказе в подключении в Mozilla Firefox

Если простого условия о наличии SSL-сертификата, подписанного корпоративным СА недостаточно, то на основе параметра SSLRequire можно реализовать более сложные проверки, которые будут учитывать различные параметры сертификата.

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

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

Заключение

C точки зрения организации безопасной ИТ-среды Web-ресурсы любой компании в первую очередь нуждаются в защите HTTP-трафика, причем, как правило, необходимо не только сгенерировать ключи для всех используемых серверов, но и организовать их разделение по портам, так как из-за требований протокола HTTPS на одном физическом сервере на одном и том же порту нельзя разместить несколько виртуальных Web-серверов с поддержкой HTTPS.

Дополнительно следует продумать вопрос, необходимо ли ограничить круг пользователей, которые будут иметь доступ к указанным Web-ресурсам. Если такая необходимость возникнет, то для всех пользователей потребуется сгенерировать клиентские SSL-сертификаты, обеспечить регулярное обновление CRL для отзыва аннулированных сертификатов и активировать поддержку CRL на Web-сайте, доступ к которому должен быть ограничен.

Записки IT специалиста

Технический блог специалистов ООО»Интерфейс»

  • Главная
  • Windows Server. Создание автономного центра сертификации.

Windows Server. Создание автономного центра сертификации.

  • Автор: Уваров А.С.
  • 19.11.2010

Перед каждым администратором рано или поздно возникает необходимость обеспечить безопасный обмен информации через интернет, внешние и внутренние сети, а также проверку подлинности каждой из сторон, участвующих в обмене информацией. На помощь здесь приходит инфраструктура открытых ключей (PKI) и службы сертификации Windows.

Инфраструктура открытых ключей позволяет использовать цифровые сертификаты для подтверждения подлинности владельца и позволяет надежно и эффективно защищать трафик передаваемый по открытым сетям связи, а также осуществлять с их помощью аутентификацию пользователей. Основой инфраструктуры открытых ключей является центр сертификации, который осуществляет выдачу и отзыв сертификатов, а также обеспечивает проверку их подлинности.

Для чего это может быть нужно на практике? Цифровые сертификаты позволяют использовать шифрование на уровне приложений (SSL/TLS) для защиты веб-страниц, электронной почты, служб терминалов и т.п., регистрацию в домене при помощи смарт-карт, аутентификацию пользователей виртуальных частных сетей (VPN), шифрование данных на жестком диске (EFS), а также в ряде случаев обойтись без использования паролей.

Для создания центра сертификации нам понадобится сервер, работающий под управлением Windows Server, который может быть как выделенным, так и совмещать роль центра сертификации с другими ролями. Однако следует помнить, что после развертывания центра сертификации вы не сможете поменять имя компьютера и его принадлежность к домену (рабочей группе).

Центр сертификации (ЦС) может быть двух типов: ЦС предприятия и изолированный (автономный) ЦС, рассмотрим их отличительные особенности:

ЦС предприятия

  • Требует наличия ActiveDirectory
  • Автоматическое подтверждение сертификатов
  • Автоматическое развертывание сертификатов
  • Возможность запроса сертификатов через Web-интерфейс, мастер запросов и автоматическое развертывание

Изолированный (автономный) ЦС

  • Не требует наличия ActiveDirectory
  • Ручное подтверждение сертификатов
  • Отсутствие возможности автоматического развертывания
  • Запрос сертификатов только через Web-интерфейс

Методика развертывания ЦС для Windows Server 2003 и Windows Server 2008 несколько различаются, поэтому мы решили рассмотреть их в отдельности.

Windows Server 2003

Для возможности использования Web-интерфейса для выдачи сертификатов нам понадобится установленный web-сервер IIS. Установим его через диспетчер сервера: Пуск — Управление данным сервером — Добавить или удалить роль.
В списке ролей выбираем роль Сервера приложений. В следующем окне устанавливаем галочку Включить ASP.NET, если IIS уже установлен данный шаг можно пропустить.

После установки IIS приступим к развертыванию Центра сертификации, это делается через оснастку Установка и удаление программ — Установка компонентов Windows, где выбираем Службы сертификации.

Следующим шагом выберите тип ЦС и его подчиненность. Так как в нашем случае сеть не имеет доменной структуры, то ЦС Предприятия недоступен для выбора. Поскольку это первый (и пока единственный ЦС) следует выбрать корневой сервер, подчиненный тип следует выбирать для развертывания следующих ЦС, например для филиалов.

Далее вводим имя ЦС (должно совпадать с именем сервера) и пути размещения файлов. В процессе установки программа предложит перезапустить IIS и, если не была включена поддержка страниц ASP.NET, предложит ее включить, с чем следует согласиться.

Windows Server 2008 R2

В Windows Server 2008 (2008 R2) все настройки консолидированы в одном месте, что делает установку ЦС более простой и удобной. Выбираем Диспетчер сервера — Роли — Добавить роли, в списке ролей выбираем Службы сертификации Active Directory.

В следующем окне обязательно добавляем компонент Служба регистрации в центре сертификации через интернет. При этом будут автоматически определены необходимые службы ролей и компоненты (такие как IIS) и будет предложено их добавить.

Дальнейшая настройка аналогична Windows Server 2003. Вводим тип ЦС, его имя и место хранения файлов, подтверждаем выбор компонент и завершаем установку.

Проверка работы ЦС

Для первоначальной проверки работоспособности ЦС можете запустить оснастку Центр сертификации (Пуск — Администрирование — Центр Сертификации). Если все сделано правильно вы должны увидеть следующее окно:
Попробуем теперь получить сертификат для клиентского ПК. Запустим браузер, в адресной строке которого укажем адрес http://имя_сервера/certsrv, где имя_сервера — имя сервера ЦС. Вы попадете на главную страницу центра сертификации.
Прежде всего необходимо загрузить сертификат ЦС и поместить его в хранилище доверенных коренных центров сертификации. Если в вашей сети несколько ЦС следует загрузить и установить цепочку сертификатов. Для этого выбираем: Загрузка сертификата ЦС, цепочки сертификатов или CRL, затем Загрузка сертификата ЦС или Загрузка сертификата ЦС и сохраняем сертификат в любое удобное место.

Теперь перейдем к установке, для этого щелкнем правой кнопкой на файле сертификата и выберем Установить сертификат, откроется мастер импорта, в котором откажемся от автоматического выбора хранилища вручную выбрав Доверенные корневые центры сертификации, теперь данный ПК будет доверять всем сертификатам выданным данным ЦС.

Для получения клиентского сертификата снова откроем сайт ЦС и выберем Запрос сертификата — расширенный запрос сертификатаСоздать и выдать запрос к этому ЦС. Заполняем форму запроса, в качестве имени указываем имя ПК или пользователя, в качестве типа сертификата указываем Сертификат проверки подлинности клиента и жмем кнопку Выдать.

При попытке создать запрос сертификата вы можете получить следующее предупреждение:

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

Теперь на сервере откроем оснастку Центр сертификации и в разделе Запросы на ожидание найдем наш запрос и щелкнув на него правой кнопкой выберем Все задачи — Выдать.

Теперь вернемся на клиентский ПК и еще раз откроем сайт ЦС. На этот раз выберем Просмотр состояния ожидаемого запроса сертификата, вы увидите свой запрос, щелкнув на которой вы попадете на страницу Сертификат выдан и сможете сразу его установить.

Если все сделано правильно, то сертификат успешно установится в хранилище личных сертификатов.

По окончании проверки не забудьте удалить ненужные сертификаты с клиентского ПК и отозвать их в центре сертификации на сервере.

Авторизация по SSL сертификатам

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

Реализовать этот механизм можно с помощью Apache и его модуля mod_ssl. Для этого понадобится:

Конфигурация сервера для запроса и проверки клиентских сертификатов

Настроим один из серверов, рассмотренных в предыдущей статье, для авторизации по клиентским сертификатам. К примеру citename.ru. CA для него уже создан. По этому начнем с настройки виртуального хоста. В файл настроек нужно добавить следующее:

Примечание
SSLCACertificateFile Абсолютный путь к файлу доверенного сертификата (CA)
SSLVerifyClient require Требование предоставить сертификат для авторизации.
Если сертификат не будет предоставлен — доступ будет запрещен.

Секция VirtualHost для citename.ru должна выглядеть так:

ServerName citename.ru
ServerAdmin Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.

DocumentRoot «/var/www/localhost/htdocs»

Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all

TransferLog /var/log/apache2/ssl_citename_access_log
CustomLog /var/log/apache2/ssl_citename_request_log \
«%t %h %x %x \»%r\» %b»

SSLEngine on
SSLVerifyClient require
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL


SSLCertificateFile /etc/apache2/ssl/citename-CA.crt
SSLCertificateKeyFile /etc/apache2/ssl/citename-CA.key
SSLCACertificateFile /etc/apache2/ssl/citename-CA.crt

Теперь можно сказать Apache перечитать конфигурацию

Создание клиентского сертификата

Подготовим структуру каталогов и файлов для хранилища сертификатов.

В каталоге db/certs будем хранить выданные сертификаты. В файле db/index.txt будут храниться данные о выданных сертификатах. А в файле db/serial — серийный номер для нового сертификата.

Создаем конфигурационный файл для подписи сертификатов.

/etc/apache2/vhosts.d/citename_ssl_vhost.conf

[ ca ]
default_ca = CA_CITENAME # Секция по умолчанию для подписи сертификатов

[ CA_CITENAME ]
droot = /etc/ssl/citename.ru # Корневой каталог хранилища
dir = $droot/db # Каталог базы хранилища
certs = $dir/certs # Каталог сертификатов
new_certs_dir = $dir/newcerts # Каталог для новых сертификатов (pem)

database = $dir/index.txt # Файл базы сертификатов
serial = $dir/serial # Файл серийного номера

# Файл доверенного сертификата
certificate = /etc/apache2/ssl/citename-CA.crt
# Закрытый ключ доверенного сертификата
private_key = /etc/apache2/ssl/citename-CA.key

default_days = 365 # Срок действия нового сертификата (дни)
default_crl_days = 7 # Срок действия списка отозванных сертификатов
default_md = md5 # Использовать алгоритм MD5

policy = policy_citename # Политика секции

[ policy_citename ]
countryName = optional # Необязательный параметр
stateOrProvinceName = optional # …………………..
localityName = optional # …………………..
organizationName = optional # …………………..
organizationalUnitName = optional # …………………..
commonName = supplied # обязательный параметр
emailAddress = supplied # …………………

Создаем запрос на клиентский сертификат.

/etc/ssl/citename.ru/citename-CA.conf

C — Двухсимвольное обозначение страны
ST — Республика/Регион/Край/Область
L — Населённый пункт
O — Организация
OU — Подразделение организации
CN — Имя сертификата. Если генерится для сервера — должно указываться имя сервера.
emailAddress — и так вроде понятно

req Генерация нового сертификата
-new Запрос на подпись сертификата
-newkey rsa:1024 Новый закрытый RSA ключ длиной 1024 бита
-nodes Не шифровать закрытый ключ
-keyout user01.key Закрытый ключ сохранить в user01.key
-days 365 Срок действия сертификата
-subj Информация о владельце сертификата.
-out user01.csr Запрос на сертификат сохранить в user01.csr

Результатом команды будут два файла: закрытый ключ user01.key и запрос на сертификат user01.csr . Проверим что у нас получилось.

Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=RU, ST=Arkh, L=Arkh, O=OAO, OU=Sales, CN=user01/emailAddress= Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:d9:18:df:76:81:90:3b:f1:2f:05:bd:e1:bc:a1:
a8:0f:6d:ad:92:8c:ae:86:28:79:16:db:6a:7f:1a:
d7:38:98:78:e3:52:70:26:9a:b2:9c:1f:80:f7:d6:
99:82:f7:55:7d:a2:57:78:63:28:cd:70:93:96:a6:
d3:40:55:20:d0:45:f2:7d:8f:d1:83:0d:50:2b:d3:
ed:71:c6:2d:af:0a:8b:92:55:2b:25:17:22:3d:71:
db:ee:ef:95:e7:52:d6:aa:46:31:e2:ee:c5:09:78:
d4:78:a7:f0:f0:0b:4f:bb:38:2b:3b:2d:46:99:49:
6b:aa:42:e0:67:7c:1c:4c:5b
Exponent: 65537 (0x10001)
Attributes:
a0:00
Signature Algorithm: sha1WithRSAEncryption
14:81:32:d3:32:ef:a8:fd:03:7a:91:0c:7c:73:b7:9c:a8:59:
3a:18:27:30:48:6a:0c:9a:47:1f:91:12:2e:5a:8e:fd:15:37:
05:c4:6f:04:16:51:f0:7b:b6:50:ce:08:b1:ce:5f:e6:4a:a1:
f2:df:c5:e6:fb:cd:29:2d:32:fc:6b:cc:52:52:f6:ba:4b:88:
d3:cd:97:14:7c:49:f5:03:82:ca:14:74:d0:6f:20:07:bc:8e:
42:41:3c:61:17:a5:36:32:e8:08:95:18:c7:f8:63:5f:18:82:
76:70:65:b1:c9:fe:d9:5d:e3:cf:f8:c4:08:54:dd:ca:af:f5:
77:96
Private-Key: (1024 bit)
modulus:
00:d9:18:df:76:81:90:3b:f1:2f:05:bd:e1:bc:a1:
a8:0f:6d:ad:92:8c:ae:86:28:79:16:db:6a:7f:1a:
d7:38:98:78:e3:52:70:26:9a:b2:9c:1f:80:f7:d6:
99:82:f7:55:7d:a2:57:78:63:28:cd:70:93:96:a6:
d3:40:55:20:d0:45:f2:7d:8f:d1:83:0d:50:2b:d3:
ed:71:c6:2d:af:0a:8b:92:55:2b:25:17:22:3d:71:
db:ee:ef:95:e7:52:d6:aa:46:31:e2:ee:c5:09:78:
d4:78:a7:f0:f0:0b:4f:bb:38:2b:3b:2d:46:99:49:
6b:aa:42:e0:67:7c:1c:4c:5b
publicExponent: 65537 (0x10001)
privateExponent:
5a:c5:85:99:bd:2e:9b:81:8a:91:b2:05:12:a3:dc:
eb:26:86:ae:81:d7:ef:0c:39:25:0f:75:05:d4:29:
2c:e6:c3:94:f8:c1:1f:c3:0a:ef:30:54:f2:4b:6e:
40:4e:3e:16:9b:ac:4b:0f:da:dd:9b:36:7a:85:22:
4b:01:cd:07:c3:32:26:31:d8:b1:fd:fa:d0:64:8b:
3d:48:ba:be:f0:3a:82:3a:08:b8:da:18:7c:41:2f:
05:7f:bc:09:25:21:a2:17:ec:b0:dd:36:e8:79:f4:
4a:70:14:f1:d0:22:ad:8a:0b:d8:30:2e:ee:50:f3:
77:c2:6d:48:c1:a5:dc:41
prime1:
00:ed:13:50:fb:cd:03:83:1d:d3:48:02:3b:bd:12:
b8:9a:bd:4d:4a:6e:b3:53:16:b6:67:f0:74:53:89:
1f:2c:45:46:16:36:ee:88:aa:7c:b5:2a:f0:c0:c0:
b3:ee:24:2f:b3:7c:19:9a:c8:8a:09:18:79:a4:a8:
25:38:12:28:2b
prime2:
00:ea:6d:4b:d1:b4:d3:ee:c0:24:1f:83:61:a5:67:
33:18:da:1c:90:cf:23:bb:06:c7:3e:21:c0:77:00:
9c:1e:52:18:38:23:61:93:27:a1:d0:61:1f:ad:0c:
14:ad:d2:ae:eb:4e:7d:c8:03:89:f4:8a:a3:c1:2b:
51:64:48:a4:91
exponent1:
00:95:ca:5e:a0:ba:28:3d:ef:da:4e:e5:1a:59:9c:
3a:87:8a:94:0b:33:66:9a:58:ff:67:2c:c6:53:01:
90:70:a8:54:60:34:d5:02:04:b6:46:c1:9a:dc:2e:
e5:80:d1:dc:51:cb:57:62:34:d3:02:6c:34:6f:94:
cd:ef:5f:89:81
exponent2:
26:19:4b:38:32:b6:3a:d8:19:46:d1:d8:5d:c4:4e:
e6:9c:14:06:68:d3:ba:c2:98:40:fd:c5:44:d1:e1:
8d:7f:f4:15:b3:92:59:13:18:d6:3f:e2:a1:02:14:
9e:47:5e:4c:39:be:71:72:39:ca:77:79:b3:9c:31:
a7:25:b3:31
coefficient:
19:e7:3a:5b:2d:75:4f:26:ab:f1:4b:8a:9e:c1:32:
40:9e:6e:a8:bb:8a:5f:36:8a:f1:30:39:37:01:59:
6c:7e:67:35:3f:bd:fc:3e:eb:fb:b9:a6:af:7c:9d:
7f:c3:83:d1:6e:11:d6:0d:56:05:9b:07:fd:27:32:
22:8c:cf:61

Подпишем сертификат ключом сервера.

Результатом команды будет вывод на экран что-то вроде этого:

Using configuration from citename-CA.conf
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
countryName :PRINTABLE:’RU’
stateOrProvinceName :ASN.1 12:’Arkh’
localityName :ASN.1 12:’Arkh’
organizationName :ASN.1 12:’OAO’
organizationalUnitName:ASN.1 12:’Sales’
commonName :ASN.1 12:’user01′
emailAddress :IA5STRING:’ Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. ‘
Certificate is to be certified until Jan 30 18:58:53 2020 GMT (365 days)

Write out database with 1 new entries
Data Base Updated

И файл подписанного сертификата user01.crt .

ca Подпись запроса на сертификат доверенным сертификатом
-config citename-CA.conf Использовать конфигурационный файл citename-CA.conf
-in user01.csr Файл запроса на сертификат находится в user01.csr
-out user01.crt Подписанный сертификат сохранить в user01.crt
-batch Не задавать вопросов и автоматически сертифицировать

Проверим что получилось.

Certificate:
Data:
Version: 1 (0x0)
Serial Number: 2 (0x2)
Signature Algorithm: md5WithRSAEncryption
Issuer: C=RU, ST=Arkh, L=Arkh, O=OAO, OU=Sales, CN=citename.ru/emailAddress= Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.
Validity
Not Before: Jan 30 18:58:53 2020 GMT
Not After : Jan 30 18:58:53 2020 GMT
Subject: C=RU, ST=Arkh, L=Arkh, O=OAO, OU=Sales, CN=user01/emailAddress= Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:d9:18:df:76:81:90:3b:f1:2f:05:bd:e1:bc:a1:
a8:0f:6d:ad:92:8c:ae:86:28:79:16:db:6a:7f:1a:
d7:38:98:78:e3:52:70:26:9a:b2:9c:1f:80:f7:d6:
99:82:f7:55:7d:a2:57:78:63:28:cd:70:93:96:a6:
d3:40:55:20:d0:45:f2:7d:8f:d1:83:0d:50:2b:d3:
ed:71:c6:2d:af:0a:8b:92:55:2b:25:17:22:3d:71:
db:ee:ef:95:e7:52:d6:aa:46:31:e2:ee:c5:09:78:
d4:78:a7:f0:f0:0b:4f:bb:38:2b:3b:2d:46:99:49:
6b:aa:42:e0:67:7c:1c:4c:5b
Exponent: 65537 (0x10001)
Signature Algorithm: md5WithRSAEncryption
72:e5:e6:7d:e2:c1:fd:63:d1:55:72:96:2c:92:e2:1b:7f:b8:
fc:d7:0e:ce:72:dc:24:3d:f4:db:27:79:26:c8:17:15:7f:fe:
c4:36:6e:32:9e:40:20:c5:b6:30:ae:ee:3c:12:36:3a:45:1b:
cc:d5:92:f6:72:d7:9d:84:b8:71:16:03:26:a9:2b:43:2a:68:
06:91:ff:76:5b:46:98:07:18:d5:2f:2c:81:97:5c:80:f7:1d:
55:d5:13:2e:25:10:82:ea:33:13:3c:a5:1d:c2:18:dd:e5:7c:
f0:05:1e:ae:2a:80:01:3f:69:f4:c5:7f:da:18:b8:e9:29:90:
67:0c

Подготовим сертификат для передачи пользователю.

pkcs12 Работать с файлом в формате PKCS#12.
-export Экспортировать сертификат в файл
-in user01.crt Клиентский сертификат
-inkey user01.key Закрытый ключ клиентского сертификата
-certfile Доверенный сертификат
-out user01.p12 Сертификат в формате PKCS#12 для передачи пользователю
-passout pass:passwordkey Закрыть файл паролем passwordkey

Клиентский сертификат готов. Хранится он в файле user01.p12 . Теперь его можно передать пользователю для установки в браузер.

Переместим все созданные файлы в каталог db/certs на хранение.

Скрипт для создания клиентских сертификатов

Если сертификаты нужно создавать на регулярной основе — можно воспользоваться скриптом

### ================================================================================= ###
### ПЕРЕМЕННЫЕ (ПРАВИТЬ ПОД СЕБЯ) ###
BASE_DIR=»/etc/ssl/citename.ru» # Путь к хранилищу сертификатов
CA_CFG=»$BASE_DIR/citename-CA.conf» # Конфигурационный файл для подписи
CERTS=»$BASE_DIR/db/certs» # Каталог для хранения сертификатов
CA_FILE=»/etc/apache2/ssl/citename-CA.crt» # Доверенный сертификат (Им подписывам)
RAR=»/opt/bin/rar» # RAR. Потому что можно им паролить архив
### ================================================================================= ###

usage () <
echo «Скрипт `basename $0` предназначен для создания клиентских SSL сертификатов.»
echo «»
echo «Использование: `basename $0` -c C -t ST -l L -o O -u OU -n CN -e eml -p pw -r -s»
echo -e » \033[1mОпции:\033[0m»
echo » -c Двухсимвольный код страны. C сертификата»
echo » -e E-Mail сертификата. Также используется для отправки сертификата»
echo » пользователю если установлена опция -s. Обязательная опция!»
echo » -l Населенный пункт. L сертификата.»
echo » -n Наименование (CN) сертификата. Также используется для наименования файлов»
echo » сертификата. Обязательная опция.»
echo » -o Организация. O сертификата.»
echo » -p Пароль сертификата. Также используется для пароля архива, если указана -s.»
echo » -r Показывать содержимое сертификатов.»
echo » -s Отправить упакованный сертификат пользователю по электронной почте,»
echo » указанной в опции -e»
echo » -t Республика/Регион/Край/Область. ST сертификата.»
echo » -u Подразделение организации для которой выдается сертификат. OU сертификата.»
echo -e » \033[1mОБРАТИТЕ ВНИМАНИЕ!\033[0m Опции \033[1m-n\033[0m и \033[1m-e\033[0m являются ОБЯЗАТЕЛЬНЫМИ.»
>

# У getopts есть неприятная фича/баг. Если у опции с аргументом не введен аргумент,
# а за ней введена следующая опция, то аргументом первой опции будет вторая опция…
# Такой хоккей нам не нужен. (с) Будем с ним бороться с помощью argchk.
argchk () <

^-[n/p/e/c/t/l/o/u]$ ]]
then
echo «Неправильный аргумент $OPTARG для опции -$Option!»
usage
exit 1
fi
>


if [ $# -eq «$NO_ARGS» ] # Сценарий вызван без аргументов?
then
usage # Если запущен без «аргуменотов» — вывести справку
exit $E_OPTERROR # и выйти с кодом ошибки
fi

while getopts «rsn:p:e:c:t:l:o:u:» Option
do
case $Option in
n ) argchk
C_NAME=»$OPTARG-$(date ‘+%F’)» # добавляем дату к имени сертификата, чтобы в базе
# не было совпадений имен сертификатов
CN=»/CN=$OPTARG»;;
p ) argchk
PW=$OPTARG;;
e ) argchk
EML=$OPTARG
E=»/emailAddress=$OPTARG»;;
c ) argchk
C=»/C=$OPTARG»;;
t ) argchk
ST=»/ST=$OPTARG»;;
l ) argchk
L=»/L=$OPTARG»;;
o ) argchk
O=»/O=$OPTARG»;;
u ) argchk
OU=»/OU=$OPTARG»;;
r ) SH_RES=1;;
s ) SEND_EMAIL=1;;
* ) echo «Выбран недопустимый ключ.»

exit $E_OPTERROR;; # ПО-УМОЛЧАНИЮ
esac
done
shift $(($OPTIND — 1))

# Проверка обязательных опций
if [ -z $CN ] || [ -z $E ]
then
echo «Опции -n и -e являются ОБЯЗАТЕЛЬНЫМИ!»
usage
exit 5
fi

# Проверим указан ли пароль
if [ -z $PW ]
then
RARPW=»»
else
RARPW=»-p$PW»
fi

# Создаем запрос на сертификат
openssl req -new -newkey rsa:1024 -nodes -keyout «$BASE_DIR/$C_NAME.key» -subj «$SUBJ» -out «$BASE_DIR/$C_NAME.csr»

if ! [ -z $SH_RES ] # Если указана опция -r
then
# Показать содержимое запроса на сертификат
openssl req -noout -text -in «$BASE_DIR/$C_NAME.csr»
fi

# Подписываем сертификат
openssl ca -config «$CA_CFG» -in «$BASE_DIR/$C_NAME.csr» -out «$BASE_DIR/$C_NAME.crt» -batch

if ! [ -z $SH_RES ] # Если указана опция -r
then
# Показать содержимое сертификата

openssl x509 -noout -text -in «$BASE_DIR/$C_NAME.crt»
fi

# Упаковать сертификат в файл PKCS#12
openssl pkcs12 -export -in «$BASE_DIR/$C_NAME.crt» -inkey «$BASE_DIR/$C_NAME.key» \
-certfile «$CA_FILE» -out «$BASE_DIR/$C_NAME.p12» -passout pass:$PW

if [ $SEND_EMAIL -eq 1 ] # Если указана опция -s
then
# Упаковать файл PKCS#12 в архив
$RAR a -ep $RARPW «$BASE_DIR/$C_NAME.rar» «$BASE_DIR/$C_NAME.p12»
# и отправить пользователю по электронке
uuencode «$BASE_DIR/$C_NAME.rar» «$C_NAME.rar» | mail -s «$C_NAME.rar» $EML && \
echo «Сертификат отправлен по адресу: $EML»
fi

mv $BASE_DIR/$C_NAME.* «$CERTS»

Для корректной работы скрипта требуется наличие установленных программ: mail-client/mailx (mail — консольный клиент для отправки почтовых сообщений, app-arch/rar (архиватор), app-arch/sharutils (перекодировщик двоичных файлов в текстовый вид для почтовых вложений).

Поддержка и настройка защиты сервисов ASP.NET Web API

Продукты и технологии:

ASP.NET Web API

В статье рассматриваются:

  • предотвращение атак с подделкой кросс-сайтовых запросов (cross-site request forgery attacks);
  • применение базовой аутентификации;
  • использование из клиента, отличного от JavaScript;
  • работа с клиентскими сертификатами;
  • защита запросов в резидентном сервисе (self-hosted service);
  • создание собственного обработчика сообщений Web API;
  • расширение авторизации.

Для наиболее распространенного сценария — JavaScript-код в веб-странице обращается к сервису Web API на том же сайте — обсуждать защиту ASP.NET Web API, в общем-то, излишне. При условии, что вы аутентифицируете своих пользователей и авторизуете доступ к Web Forms/Views, содержащим JavaScript, который работает с вашими сервисами, можно считать, что вся необходимая защита сервисов у вас есть. Это результат того, что ASP.NET посылает файлы cookie и информацию об аутентификации, используемые для проверки запросов страниц, как часть любого JavaScript-запроса на клиентской стороне, адресованного методам вашего сервиса. Однако имеется одно важное исключение: ASP.NET не защищает вас автоматически от атак с подделкой кросс-сайтовых запросов (Cross-Site Request Forgery, CSRF/XSRF) (подробнее об этом — позже).

Помимо CSRF, существует два сценария, в которых действительно имеет смысл обсуждать защиту сервисов Web API. Первый сценарий — сервис используется клиентом, отличным от страницы того сайта, где находятся ваши ApiController. Эти клиенты не проверяются средствами аутентификации на основе форм (Forms Authentication) и не получают файлы cookie и маркеры, используемые ASP.NET для управления доступом к вашим сервисам.

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

В Web API предлагается несколько вариантов решений для обоих сценариев. По сути, хотя я буду рассматривать защиту в контексте приема запросов Web API, следует учитывать, что Web API основан на том же фундаменте ASP.NET, что и Web Forms/MVC, а значит, средства, о которых я буду рассказывать в этой статье, должны быть знакомы любому, кому известно внутреннее устройство защиты в Web Forms или MVC.

Один подвох: Web API предоставляет вам несколько вариантов аутентификации и авторизации, но защита начинается либо с IIS, либо с хоста, который вы создаете при наличии резидентной среды хостинга (self hosting). Если вы, например, хотите гарантировать приватность коммуникаций между сервисом Web API и клиентом, то должны, как минимум, включить SSL. Однако это обязанность не столько разработчика, сколько администратора сайта. В этой статье я проигнорирую все, что относится к хосту, и сосредоточусь на том, что может и должен сделать разработчик для защиты сервиса Web API (средства, рассматриваемые здесь, будут работать независимо от того, включен SSL или нет).

Предотвращение атак с подделкой кросс-сайтовых запросов

Когда пользователь обращается к сайту ASP.NET, применяющему аутентификацию на основе форм, ASP.NET генерирует cookie, который указывает, что данный пользователь аутентифицирован. Браузер будет посылать этот cookie при каждом последующем запросе к сайту независимо от того, откуда исходит этот запрос. Это делает ваш сайт уязвимым к атакам CSRF, как и любая другая схема аутентификации, где браузер автоматически отправляет полученную ранее аутентификационную информацию. Если пользователь после такой аутентификации на вашем сайте посетит какой-нибудь злонамеренный сайт, тогда этот сайт сможет посылать запросы вашему сервису, цепляясь за cookie аутентификации, ранее полученный браузером.

Чтобы предотвратить атаки CSRF, вам потребуется генерировать на сервере маркеры, стойкие к подделке, и встраивать их в страницу, которая будет использоваться при вызовах с клиентской стороны. Microsoft предоставляет класс AntiForgery с методом GetToken. Этот метод генерирует маркеры, специфичные для пользователя, который выдал запрос (конечно, таковым может быть анонимный пользователь). Его код создает два маркера и помещает их в ASP.NET MVC ViewBag, откуда их можно использовать в View:

Любые JavaScript-вызовы сервера должны возвращать эти маркеры как часть запроса (у CSRF-сайта нет этих маркеров, и он не сможет вернуть их). Этот код (он находится в View) динамически генерирует JavaScript-вызов, который добавляет маркеры в заголовки запроса:

Чуть более сложное решение позволит вам использовать незаметный JavaScript-код за счет встраивания маркеров в скрытые поля в View. Первый шаг в этом процессе — добавление маркеров в словарь ViewData:

Теперь в View можно встроить данные в скрытые поля. Для генерации подходящего тега нужно просто передать методу Hidden в HtmlHelper значение ключа в ViewDate:

Конечный тег input будет использовать ключ ViewData для атрибутов name и id и помещать данные, извлеченные из словаря ViewData, в атрибут value. Тег input, сгенерированный на основе предыдущего кода, выглядел бы так:

Затем ваш JavaScript-код (который хранится в файле, отдельном от View) может получать значения из тегов input и использовать их в вызовах ajax:

Вы можете добиться тех же целей на сайте с ASP.NET Web Forms, используя метод RegisterClientScriptBlock объекта ClientScriptManager (извлекается из свойства ClientScript объекта Page), чтобы вставить JavaScript-код с помощью встраиваемых маркеров:

Наконец, вам понадобится проверять маркеры на сервере при их возврате JavaScript-вызовом. Разработчики, обновившие Visual Studio 2012 пакетом ASP.NET and Web Tools 2012.2, обнаружат, что новый шаблон SinglePage Application (SPA) включает фильтр ValidateHttpAntiForgeryToken, который можно использовать в методах Web API. В отсутствие этого фильтра вы должны получать маркеры и передавать их методу Validate класса AntiForgery (этот метод будет генерировать исключение, если маркер недопустим или был создан для другого пользователя). Код на рис. 1, используемый в методе сервиса Web API, получает маркеры из заголовков и проверяет их.

Рис. 1. Проверка CSRF-маркеров в методе сервиса

Применение ValidateHttpAntiForgeryToken (вместо кода в методе) переносит эту обработку на более ранние этапы в цикле (например, до связывания модели), что, безусловно, хорошо.

Почему нет ни слова об OAuth?

В этой статье OAuth игнорируется намеренно. Спецификация OAuth определяет, как клиент может получать маркеры от стороннего сервера для передачи сервису, который в свою очередь проверяет их с помощью стороннего сервера. Описание того, как обращаться к провайдеру маркеров OAuth из клиента или сервиса, выходит за рамки данной статьи.


Кроме того, начальная версия OAuth не слишком хорошо подходит для Web API. Очевидно, что одна из основных причин появления Web API — использование «облегченных» запросов на основе REST и JSON. Эта цель делает первую версию OAuth непривлекательным вариантом для сервисов Web API. Маркеры, формируемые первой версией OAuth, слишком объемистые и основаны на XML. К счастью, в OAuth 2.0 ввели спецификацию для облегченных маркеров JSON, более компактных по сравнению с маркерами из прошлых версий. Методики, рассматриваемые в этой статье, можно было бы использовать и для обработки любых OAuth-маркеров, посылаемых сервису.

Базовая аутентификация

Первая из двух основных задач в защите сервиса Web API — аутентификация (вторая задача — авторизация). Я исхожу из того, что другие задачи, например защита конфиденциальных данных, обрабатываются на хосте.

В идеале, аутентификация и авторизация будут выполняться в конвейере Web API как можно раньше, что избежать траты вычислительных ресурсов на запрос, который вы отклоните. Решения по аутентификации, обсуждаемые в этой статье, используются на самых ранних стадиях конвейера — практически в тот момент, когда поступает запрос. Эти методики также позволяют интегрировать аутентификацию с любыми списками пользователей, которые вы уже поддерживаете. Рассматриваемые методы авторизации могут применяться во многих местах конвейера (включая такие поздние стадии, как в самом методе сервиса) и работать совместно с аутентификацией, чтобы авторизовать запросы на основе некоторых других критериев, отличных от имени или роли пользователя.

Вы можете поддерживать клиенты, не проходившие аутентификацию на основе форм, предоставив свой метод аутентификации в пользовательском HTTP-модуле (я по-прежнему исхожу из того, что вы осуществляете аутентификацию не по учетным записям в Windows, а по собственному списку пользователей). Применение HTTP-модуля дает два основных преимущества: модуль участвует в HTTP-протоколировании и аудите, и его можно вызывать на самых ранних стадиях конвейера. Хотя эти возможности важны, за них приходится платить: модули являются глобальными и применяются ко всем запросам сайта, а не только к запросам Web API; кроме того, чтобы использовать модули аутентификации, вы должны разместить сервис в IIS. Позднее в этой статье я опишу применение обработчиков делегирования, вызываемых только для запросов Web API и независимых от хоста.

В этом примере использования HTTP-модуля я исхожу из того, что IIS использует базовую аутентификацию и удостоверения, применяемые для аутентификации пользователей, содержат имя и пароль пользователя и посылаются клиентом (в этой статье я буду игнорировать сертификацию в Windows, но рассмотрю применение клиентских сертификатов). Кроме того, я предполагаю, что сервис Web API защищается с использованием атрибута Authorize, например:

Первый шаг в создании собственного HTTP-модуля авторизации — добавление в проект сервиса класса, который реализует интерфейсы IHttpModule и IDisposable. В методе Init этого класса вы должны подключать два события от объекта HttpApplication, передаваемые методу. Метод, подключаемый к событию AuthenticateRequest, будет вызываться при получении удостоверений клиента. Но вы также должны подключить метод EndRequest, чтобы генерировать сообщение, заставляющее клиент посылать вам свои удостоверения. Кроме того, мне необходим метод Dispose, но вам не нужно ничего помещать в него для поддержки кода, используемого здесь:

HttpClient будет посылать удостоверения в ответ на заголовок WWW-Authenticate, включаемые вами в HTTP-ответ. Вы должны включать этот заголовок, когда запрос приводит к генерации кода 401 (ASP.NET будет генерировать код ответа 401, когда доступ клиента к защищенному сервису отклоняется). Заголовок должен содержать указание на то, какой метод аутентификации используется, и область, в которой будет применяться аутентификация (областью может быть любая произвольная строка, и она используется как флаг при просмотре различных областей на сервере). Код, посылающий это сообщение, помещается в метод, подключаемый к событию EndRequest. В следующем примере генерируется сообщение, которое указывает, что используется базовая аутентификация в области PHVIS:

В методе, где вы подключились к методу AuthenticateRequest, вы должны получить заголовки Authorization, которые клиент посылает в результате приема вашего сообщения 401/WWW-Authenticate:

Определив, что клиент передал элементы заголовка Authorization (мы по-прежнему предполагаем, что сайт использует базовую аутентификацию), вы должны разобрать данные, содержащие имя и пароль пользователя. Имя и пароль кодируются по основанию Base64 и разделяются двоеточием. Следующий код извлекает имя и пароль в строковый массив:

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

Следующий шаг — проверка имени и пароля с помощью любого подходящего вам механизма. Независимо от того, как именно вы проверяете запрос (мой код в примере ниже, конечно же, слишком прост), на последнем этапе создается идентификация для пользователя, которая будет задействована в процессах авторизации на более поздних стадиях конвейера ASP.NET.

Чтобы передать информацию идентификации по конвейеру, вы создаете объект GenericIdentity с именем идентификации, которую вы хотите назначить пользователю (в коже ниже я предполагаю, что это имя пользователя, переданное в заголовке). Создав объект GenericIdentity, вы должны поместить его в свойство CurrentPrincipal класса Thread. Кроме того, ASP.NET поддерживает второй контекст защиты в объекте HttpContext, и, если вашим хостом является IIS, вы тоже должны поддерживать его, сохраняя объект GenericIdentity в свойстве User свойства Current объекта HttpContext:

Если вам нужно поддерживать защиту на основе ролей, тогда вы должны передавать массив имен ролей как второй параметр конструктора GenericPrincipal. В этом примере каждому пользователю назначаются роли manager и admin:

Для интеграции HTTP-модуля в конвейер обработки на сайте используйте в файле web.config своего проекта тег add в элементе modules. Атрибуту type тега add должна быть присвоена строка, состоящая из полного имени класса, за которым следует имя сборки вашего модуля:

Созданный вами объект GenericIdentity будет работать с ASP.NET-атрибутом Authorize. Кроме того, вы можете обращаться к GenericIdentity из метода сервиса для выполнения операций, связанных с авторизацией. Например, вы могли бы предоставлять разные сервисы для зарегистрированных и анонимных пользователей, определяя, аутентифицирован ли данный пользователь. Для этого проверяйте свойство IsAuthenticated (IsAuthenticated возвращает false для анонимного пользователя):

Вы можете получить объект GenericIdentity более простым способом через свойство User:

Создание совместимого клиента

Чтобы работать с сервисами, защищаемыми этим модулем, клиент, отличный от JavaScript, должен предоставить правильные имя и пароль пользователя. Для передачи этих удостоверений через .NET-объект HttpClient вы сначала создаете объект HttpClientHandler и указываете в его свойстве Credentials объект NetworkCredential, содержащий имя и пароль пользователя (или устанавливаете свойство UseDefaultCredentials объекта HttpClientHandler в true, чтобы задействовать Windows-удостоверения текущего пользователя). Затем вы создаете объект HttpClient, передавая объект HttpClientHandler:

Закончив конфигурирование, вы можете отправить запрос сервису. HttpClient не предоставит удостоверения, пока доступ к сервису не будет отклонен и не будет получено сообщение WWW-Authenticate. Если удостоверения, переданные HttpClient, не принимаются, сервис возвращает HttpResponseMessage со StatusCode его Result, установленным в «unauthenticated».

Следующий код вызывает сервис, используя метод GetAsync, проверяет, получен ли результат, и, если результата нет, отображает код состояния, возвращенный сервисом:

Если предположить, что вы обходите ASP.NET-процесс входа для клиентов, отличных от JavaScript, как это сделал я, то никакие cookie аутентификации не создаются и каждый запрос от клиента проверяется индивидуально. Чтобы уменьшить издержки постоянных проверок удостоверений клиента, подумайте о кешировании удостоверений (и применении собственного метода Dispose для удаления удостоверений из кеша).

Работа с клиентскими сертификатами

В HTTP-модуле вы получаете объект клиентского сертификата (и проверяете, что он допустим и вообще имеется) с помощью такого кода:

Далее по конвейеру обработки, например в методе сервиса, вы получаете объект сертификата (проверив, что он имеется) с помощью следующего кода:

Если сертификат есть и он допустим, вы можете дополнительно проверить специфические значения в свойствах сертификата (скажем, субъект или эмитент).

Чтобы передать сертификаты с HttpClient, первым делом создайте объект WebRequestHandler вместо HttpClientHandler (WebRequestHandler поддерживает больше конфигурационных параметров, чем HttpClientHandler):

Вы можете сделать так, чтобы HttpClient автоматически вел поиск в хранилищах сертификатов клиента, установив свойство ClientCertificateOptions объекта WebRequestHandler в Automatic (значение и перечисления ClientCertificateOption):

Однако по умолчанию клиент должен явно присоединять сертификаты к WebRequestHandler из кода. Вы можете получить сертификат от одного из хранилищ сертификатов клиента так, как это делается в следующем примере, где сертификат извлекается из хранилища CurrentUser по имени эмитента:

Если пользователю был отправлен клиентский сертификат, который по какой-то причине не добавляется в хранилище сертификатов этого пользователя, то вы можете создать объект X509Certificate на основе файла сертификата:

Независимо от того, как создается X509Certificate, последние операции на клиентской стороне заключаются в добавлении сертификата к набору ClientCertificates объекта WebRequestHandler и последующем использовании сконфигурированного WebRequestHandler для создания HttpClient:

Авторизация в резидентной среде

Хотя использовать HttpModule в резидентной среде (self-hosted environment) нельзя, процесс защиты запросов на ранних стадиях конвейера обработки в такой среде все тот же: получаем удостоверения из запроса, используем эту информацию для аутентификации запроса и создаем идентификацию, передаваемую в свойство CurrentPrincipal текущего потока. Простейший механизм — создать средство проверки (validator) имени и пароля пользователя. Чтобы делать нечто большее, чем проверять комбинацию имени и пароля пользователя, можно создать делегирующий обработчик (delegating handler). Для начала рассмотрим интеграцию средства проверки имени и пароля пользователя.

Чтобы создать средство проверки (по-прежнему предполагается, что вы применяете базовую аутентификацию), вы должны создать класс, производный от UserNamePasswordValidator (вам потребуется добавить в проект ссылку на библиотеку System.IdentityModel). Единственный метод базового класса, который вам нужно переопределить, — Validate, который будет передавать имя и пароль пользователя, отправленные клиентом сервису. Как и раньше, проверив имя и пароль, вы должны создать объект GenericPrincipal и использовать его для задания свойства CurrentPrincipal класса Thread (поскольку вы не используете IIS в качестве хоста, вам не нужно устанавливать свойство User объекта HttpContext):

Следующий код создает хост для контроллера Customers с конечной точкой http://phvis.com/MyServices и указывает новое средство проверки:

Обработчики сообщений

Чтобы делать нечто большее простой проверки имени и пароля пользователя, вы можете создать обработчик сообщений Web API. Такие обработчики имеют несколько преимуществ в сравнении с HTTP-модулем: 1) обработчики сообщений не привязаны к IIS, поэтому защита, применяемая в обработчике, будет работать с любым хостом, 2) обработчики сообщений используются только Web API, а значит, они обеспечивают простой способ выполнения авторизации (и назначения идентификаций) для ваших сервисов, применяющих процесс, который отличается от используемого страницами вашего веб-сайта, и 3) вы также можете назначать обработчики сообщений конкретным маршрутам (routes), чтобы ваш код защиты вызывался, только когда в этом есть реальная необходимость.

Первый шаг в создании обработчика сообщений — написание класса, производного от DelegatingHandler, переопределение его метода SendAysnc:

Внутри этого метода (я исхожу из того, что вы создаете индивидуальный обработчик для каждого маршрута) можно настроить свойство InnerHandler объекта DelegatingHandler так, чтобы этот обработчик можно было связать в один конвейер с другими обработчиками:

В этом примере я предполагаю, что корректный запрос должен иметь простой маркер в своей строке запроса (пару «имя-значения» в виде «authToken=xyx»). Если маркер отсутствует или ему не присвоено значение xyx, возвращается код состояния 403 (Forbidden).


Сначала я преобразовываю строку запроса в набор пар «имя-значение», вызывая метод GetQueryNameValuePairs объекта HttpRequestMessage, переданного методу. Затем с помощью LINQ извлекаю маркер (или null, если маркера нет). Если маркер отсутствует или недопустим, я создаю HttpResponseMessage с подходящим кодом состояния HTTP, обертываю его в объект TaskCompletionSource и возвращаю:

Если маркер присутствует и имеет правильное значение, я создаю объект GenericPrincipal и использую его для настройки свойства CurrentPrincipal класса Thread (чтобы этот обработчик сообщений мог работать и в IIS, я также задаю свойство User объекта HttpContext, если этот объект не равен null):

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

Если ваш обработчик сообщений должен использоваться в каждом контроллере, вы можете добавить его в конвейер обработки Web API, как и любой другой обработчик сообщений. Однако, чтобы ограничить ваш обработчик использованием лишь на определенных маршрутах, вы должны добавить его через метод MapHttpRoute. Сначала создайте экземпляр своего класса, а затем передайте его как пятый параметр в MapHttpRoute (приведенный ниже код требует выражения Imports/using для System.Web.Http):

Вместо того чтобы настраивать InnerHandler в DelegatingHandler, можно настроить это свойство на диспетчер по умолчанию при определении вашего маршрута:

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

Расширение участника системы безопасности

Если авторизации по имени и роли недостаточно, можно расширить процесс авторизации, создав собственный класс участника системы безопасности (principal); при этом вы должны реализовать интерфейс IPrincipal. Однако, чтобы задействовать преимущества своего класса, вам придется создать пользовательский атрибут авторизации или добавить код в методы вашего сервиса.

Например, если у вас есть набор сервисов, к которым могут обращаться пользователи только из определенного региона, вы могли бы создать простой класс участника системы безопасности, реализующий интерфейс IPrincipal и добавляющий свойство Region, как показано на рис. 2.

Рис. 2. Создание собственного участника системы безопасности с дополнительными свойствами

Для использования преимуществ этого нового класса (который будет работать с любым хостом) достаточно создать его экземпляр, а затем с его помощью задать свойства CurrentPrincipal и User. Следующий код ищет значение в строке запроса, сопоставленное с именем «region». Получив это значение, код настраивает свойство Region участника системы безопасности и для этого передает данное значение конструктору класса:

Если вы работаете с Microsoft .NET Framework 4.5, то вместо реализации интерфейса IPrincipal вы должны наследовать от нового класса ClaimsPrincipal. Этот класс поддерживает обработку на основе заявок и интеграцию с Windows Identity Foundation (WIF). Однако этот вопрос выходит за рамки моей статьи (на эту тему мы поговорим в будущей статье, которая будет посвящена защите на основе заявок).

Авторизация собственного участника системы безопасности

Располагая новым объектом участника системы безопасности, можно создать атрибут авторизации, использующий преимущества новых данных, которые содержатся в этом объекте. Сначала создайте класс, производный от System.Web.Http.AuthorizeAttribute, и переопределите его метод IsAuthorized (этот процесс отличается от того, который принят в ASP.NET MVC, где вы создаете новые атрибуты Authorization расширением System.Web.Http.Filters.AuthorizationFilterAttribute). Методу IsAuthorized передается HttpActionContext, свойства которого можно использовать в процессе авторизации. Однако в этом примере достаточно извлечь объект участника системы безопасности из свойства CurrentPrincipal класса Thread, привести его к собственному типу участника и проверить свойство Region. Если авторизация проходит успешно, код возвращает true. В ином случае вы должны помещать в свойство Response объекта ActionContext свой ответ перед возвратом false, как показано на рис. 3.

Рис. 3. Фильтрация собственного объекта участника системы безопасности

Ваш атрибут авторизации можно использовать точно так же, как ASP.NET-фильтр Authorize по умолчанию. Поскольку в этом фильтре есть свойство Region, ему должен быть присвоен регион, принимаемый методом сервиса:

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

Как я сказал в начале статьи: в типичном сценарии Web API дополнительная авторизация не нужна ни для чего, кроме защиты от атак CSFR. Но когда у возникает потребность в расширении исходной системы безопасности, Web API предоставляет множество точек в конвейере обработки, где можно интегрировать любую необходимую защиту. А выбор — это всегда хорошо.

Питер Вогел (Peter Vogel) — один из директоров PH&V Information Services, специализируется на разработках с применением ASP.NET, эксперт в области архитектуры, ориентированной на сервисы (SOA), XML, проектировании баз данных и UI.

Выражаю благодарность за рецензирование этой статьи экспертам Доминику Байеру (Dominick Baier) из thinktecture GmbH & Co KG, а также Барри Доррансу (Barry Dorrans) и Майку Уоссону (Mike Wasson) из Microsoft.

Аутентификация клиента через сертификаты X509 в asp.net

У меня есть приложение asp.net, и мне нужно аутентифицировать пользователей, используя сертификаты X509. То есть пользователь должен установить сертификат, выданный мной, чтобы он мог просматривать мой веб-сайт, и я могу определить, каким пользователем является этот сертификат.

Я уже настроил SSL на IIS, но это не то, что я сейчас ищу, и я не знаю, с чего начать.

Как мне добиться этого в asp.net c #?

2 ответа

Чтобы создать безопасный механизм аутентификации, вы должны использовать как клиентские сертификаты, так и имя пользователя / пароль. Причина в том, что сертификат — это то, что может быть украдено (скопировано), а пароль — это то, что известно только человеку. Альтернативой может быть сертификат на смарт-карте, защищенный PIN-кодом.

Чтобы использовать клиентские сертификаты в приложениях ASP.NET, необходимо сделать следующее:

Шаг 1: В IIS Manager откройте свое приложение или веб-сайт, выберите «Настройки SSL» и выберите оба требуют SSL и требуют клиентского сертификата.

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

Важно На этом этапе вы должны убедиться, что сертификат выпущен кем-то, кому вы доверяете (поскольку каждый может создавать свои собственные самозаверяющие сертификаты).

Шаг 2: Добавить элемент конфигурации (либо web.config, база данных и т. Д.). В этот список вы добавили бы отпечатки всей цепочки CA (центра сертификации) для ваших клиентских сертификатов.

Шаг 3: Создайте классическую страницу имени пользователя и пароля. Проверьте имя пользователя / пароль.

Шаг 4: Добавьте следующий код на страницу входа в систему:

Только когда пароль и сертификат проверены, пользователь должен быть разрешен в системе. .

Предполагая, что у вас IIS 7.0 или выше, вы можете настроить аутентификацию сопоставления сертификатов клиентов

Использование Active Directory (Чрезвычайно просто, сопоставление выполняется на сервере AD)

Или с использованием IIS (в IIS требуется дополнительная настройка, требуется доступ к клиентскому сертификату, но он работает автономно, без обращений к AD). В этом случае вы указываете (один или несколько) учетных данных пользователя и

  • сопоставляете каждого пользователя с открытым ключом сертификата пользователю, чьи учетные данные вы указываете, или
  • сопоставляют несколько сертификатов с пользователь, основываясь на значениях в полях сертификата


Конфигурация (много к одному):

(Пример конфигурации довольно бесстыдно скопирован из примеров на страницах документации iis.net , что довольно сложно.)

Или вы можете настроить свое приложение на использование аутентификации на основе утверждений со службой маркеров безопасности (STS), которая аутентифицирует клиентов на основе клиентских сертификатов. ADFS 2.0 может выполнить эту роль или, если она недоступна, вы можете взглянуть на Thinktecture Identity Server .

Asp доступ к клиентским сертификатам с помощью asp

Здравстуйте, по телефону тех. поддержки Microsoft +7 (800) 200-8001 для решения моей проблемы мне порекомендавали обратиться на Ваш форум т.к. здесь помогают решить проблему Технические специалисты фирмы Microsoft!

Прочитав много информации в интернете и на данном форуме по установке авторизации к сайту на IIS по САМОЗАВЕРЕННОМУ СЕРТИФИКАТУ все равно не могу решить проблему с ошибкой:

Ошибка HTTP 403.7 — Forbidden

Страница, к которой вы пытаетесь обратиться, требует, чтобы веб-браузер имел SSL-сертификат клиента, признаваемый веб-сервером.

Делаю это я на компьютере под управлением Windows server 2008 r2 на IIS!

1. Установил IIS и опубликовал на нем сайт по http(все открывается и работает).

2. В Диспетчере служб IIS создал САМОЗАВЕРЕННЫЙ СЕРТИФИКАТ, и выгрузил его к себе на флешку.

3. В Диспетчере служб IIS на сайте изменил привязку с Http(порт 80) на HTTPS(порт 443) и указал созданный мной сертификат.

4. В Диспетчере служб IIS в настройках самого сайта изменил Параметры SSL — поставил галку Требовать SSL и там же выбрал Требовать сертификаты клиента.

5. Перезагрузил Сервер.

6. Попробовал зайти на сайт с самого сервера по адресу https://localhost/. Выдал — Ошибка HTTP 403.7 — Forbidden(хотя наверно уже должно заходить т.к. сертификат автоматом устанавливается на комп где он создается)

7. Беру флешку с сертификатом и устанавливаю сертификат на другой комп(устанавливаю Доверенные корневые центры сертификации (в Личные тоже пробовал)).

8. С клиентского компа захожу https://server/ — Выдает 403 — запрещено. Доступ запрещен.

Для изучения данной проблемы пользовался следующими ссылками:

Данные материалы не полностью подходят под решение моей проблемы в первой ссылке участвует Центр Сертификации а во второй и без сертификата будет доступен сайт..

Помогите пожалуйста.. Что же нужно сделать чтоб все заработало. Напишите пожалуйста попунктно.

Ответы

Я тут не один на форуме ) Итак, я понял вашу задачу, как создать сайт, доступ к которому будет ограничен — у кого нет сертификата, нет и доступа. В таком случае, диспетчер служб не поможет, нужно действовать иначе. И, сразу скажу, «самозаверенный» сертификат сервер тоже не признает, будет ошибка. Но если сделать самозаверенное CA — все получится. Последовательность действий:

1. Установить на Web-сервер makecert.exe из пакета SDK http://go.microsoft.com/fwlink/p/?link >

2. Выполнить на сервере команду:

3. Выполнить на сервере команду:

(здесь замените слово webserver на имя вашего сервера, больше ничего не меняйте)

4. Выполнить на сервере команду:

Здесь можно заменить слово Client на любой удобный идентификатор.

5. Включить Требовать SSL и выбрал Требовать сертификат клиента.

6. Привязать к SSL на сайте сертификат, созданный на шаге 3.

7. Проверка — заходим на сервер локально, должно пустить.

8. Удаляем из Доверенных корневых центров сертификации компьютера все, кроме WebSSLRoot. (иначе с любым сертификатом, заверенным одним из этих центров, можно будет зайти)

9. Из оснастки «Сертификаты» выгружаем персональный сертификат Client (шаг 4) вместе с ключом и из доверенных корневых центров сертификации — «WebSSLRoot» без ключа.

10. Теперь для подключения на любом компьютере ставим два сертификата с шага 9 (Client в личные, WebSSLRoot — в доверенные корневые). Можно с этого компьютера подключаться.

  • Помечено в качестве ответа Cr_MEn 25 апреля 2014 г. 8:19

Все ответы

«В Диспетчере служб IIS в настройках самого сайта изменил Параметры SSL — поставил галку Требовать SSL и там же выбрал Требовать сертификаты клиента.»


То есть вы потребовали, чтобы клиент предоставил серверу сертификат. Это входит в ваш сценарий? Если вы поставите «Игнорировать сертификат клиента», у вас должно получиться зайти.

Или вы хотите, чтобы клиент заходил с самоподписанным сертификатом (т.е. самоподписанный сертификат клиента, а не сервера)? Уточните пожалуйста целевую архитектуру Вашей системы?

****То есть вы потребовали, чтобы клиент предоставил серверу сертификат. Это входит в ваш сценарий? ****

****Если вы поставите «Игнорировать сертификат клиента», у вас должно получиться зайти.****

В данном случае заходить будет!, но не только у меня а у всех))), и вся суть настройки доступа по сертификату потеряется))). У меня даже в теме ВОПРОСА все написано. ))).

**** Или вы хотите, чтобы клиент заходил с самоподписанным сертификатом (т.е. самоподписанный сертификат клиента, а не сервера)?****

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

Pavel Kingsep не дайте мне разочароваться в данном форуме))).

Я тут не один на форуме ) Итак, я понял вашу задачу, как создать сайт, доступ к которому будет ограничен — у кого нет сертификата, нет и доступа. В таком случае, диспетчер служб не поможет, нужно действовать иначе. И, сразу скажу, «самозаверенный» сертификат сервер тоже не признает, будет ошибка. Но если сделать самозаверенное CA — все получится. Последовательность действий:

1. Установить на Web-сервер makecert.exe из пакета SDK http://go.microsoft.com/fwlink/p/?link >

2. Выполнить на сервере команду:

3. Выполнить на сервере команду:

(здесь замените слово webserver на имя вашего сервера, больше ничего не меняйте)

4. Выполнить на сервере команду:

Здесь можно заменить слово Client на любой удобный идентификатор.

5. Включить Требовать SSL и выбрал Требовать сертификат клиента.

6. Привязать к SSL на сайте сертификат, созданный на шаге 3.

7. Проверка — заходим на сервер локально, должно пустить.

8. Удаляем из Доверенных корневых центров сертификации компьютера все, кроме WebSSLRoot. (иначе с любым сертификатом, заверенным одним из этих центров, можно будет зайти)

9. Из оснастки «Сертификаты» выгружаем персональный сертификат Client (шаг 4) вместе с ключом и из доверенных корневых центров сертификации — «WebSSLRoot» без ключа.

10. Теперь для подключения на любом компьютере ставим два сертификата с шага 9 (Client в личные, WebSSLRoot — в доверенные корневые). Можно с этого компьютера подключаться.

  • Помечено в качестве ответа Cr_MEn 25 апреля 2014 г. 8:19

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

Но уже появились вопросы:

1. Можно ли сертификаты которые создались, взять выгрузить и уже без помощи makecert.exe просто импортировать на другой сервер, так же будет все работать?

2 . makecert.exe — преднозначен для тестирования работы серверов а не для безопасного доступа(т.е. есть вероятность взлома или подбора сертификата)?

3. если я все удаляю из Доверенных корневых сертификатов то после перезагрузки они опять восстанавливаются это нормально?

4. Если Самозаверенный сертификат который создается в диспетчере ISS не работает зачем тогда он нужен вообще?

1) Вероятность взлома или подбора минимальна. Клич 2048 бит. Тут большая проблема с отзывом сертификатов. Т.е. предположим, ваш клиентский сертификат украли. У вас нет никакого способа запретить его использование, кроме как перевыпустить всю сертификационную подсистему.

2) Вообще я писал вчера ночью несколько уставшим. это не очень правильно — их удалять. Нужно сделать CTL, вот статья на эту тему http://blogs.msdn.com/b/varunm/archive/2013/06/11/how-to-create-custom-certificate-trust-list-in-windows-server-2k8-r2.aspx. Действительно, системные сертификаты частично восстанавливаются, полагаю это внутренний механизм Windows (если у вас нет group policy, в которой они прописаны).

3) Он работает для сценария «нужна защита канала». Более того, подозреваю, что в том варианте, что я расписал, сертификат сервера тоже можно использовать самоподписанный. Но его нельзя использовать в качестве клиентского сертификата.

У каждого сертификата есть политики применения. Одна из них — подтверждать подлинность сервера, другая — подтверждать подлинность клиента (и еще много иных). Они лежат в параметрах сертификата Key Usage и Extended Key Usage. Далее:

Для того, чтобы IE презентовал сертификат серверу в качестве идентификатора, клиент должен владеть секретным ключом данного сертификата, в Key Usage (если есть) должно быть Digital Signature, в Extended Key Usage, если есть, должен быть OID Client Auth (1.3.6.1.5.5.7.3.2) — это поведение по умолчанию. У того сертификата, который генерируется на сервере (самоподписанного) — KU и EKU не подходят для идентификации.

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

Как получить доступ к стороннему компоненту с помощью ASP.NET и JKS-сертификата?

Мне нужно получить доступ к стороннему приложению, для которого требуется сертификат JKS (который у меня есть).

Мое клиентское приложение — ASP.NET. Как мне это сделать?

(Я хотел бы предоставить больше информации, но, к сожалению, у меня ее нет!)

1 ответ

Сначала импортируйте сертификат в хранилище сертификатов Windows. Посмотрите на http://tjworld.net/software/codesigning/JKS2PFX.html для этого. Если вам нужно использовать его из учетной записи aspnet, вы можете импортировать его в хранилище компьютеров (а не в хранилище сертификатов своих учетных записей). Используйте MMC, надписи сертификатов, чтобы проверить это.

Затем используйте этот сертификат в вашем приложении. В большинстве случаев вы выбираете его по свойству «DN = . » (которое вы также увидите в MMC).

Как предоставить ASP.NET доступ к закрытому ключу в сертификате в хранилище сертификатов?

У меня есть приложение ASP.NET, которое обращается к закрытому ключу в сертификате в хранилище сертификатов. В Windows Server 2003 я смог использовать winhttpcertcfg.exe, чтобы предоставить доступ к секретному ключу в учетной записи NETWORK SERVICE. Как предоставить разрешения для доступа к закрытому ключу в сертификате в хранилище сертификатов (локальный компьютер\личный) на Windows Server 2008 R2 на веб-сайте IIS 7.5?

Я попытался предоставить полный доступ доверия всем «всем», «IIS AppPool\DefaultAppPool», «IIS_IUSRS» и любой другой учетной записи безопасности, которую я смог найти с помощью MMC сертификатов (Server 2008 R2). Однако приведенный ниже код демонстрирует, что код не имеет доступа к закрытому ключу сертификата, который был импортирован с помощью закрытого ключа. Вместо этого код генерирует и генерирует ошибки при каждом доступе к свойствам закрытого ключа.

Default.aspx

Default.aspx.cs

  • Создать/купить сертификат. Убедитесь, что у него есть закрытый ключ.
  • Импортировать сертификат в учетную запись «Локальный компьютер» . Лучше всего использовать сертификаты MMC. Обязательно установите флажок «Разрешить доступ к закрытому ключу»

Исходя из этого, идентификатор пула приложений IIS 7.5 использует одно из следующих.

  • Веб-сайт IIS 7.5 работает под ApplicationPoolIdentity. Открыть MMC = > Добавить сертификаты (локальный компьютер) snap-in = > Сертификаты (локальный компьютер) = > Личные = > Сертификаты = > Щелкните правой кнопкой мыши интересующий сертификат = > Все задачи = > Управление закрытым ключом = > Добавить IIS AppPool\AppPoolName и дайте ему Full control . Замените «AppPoolName» на имя вашего пула приложений (иногда IIS_IUSRS )
  • Веб-сайт IIS 7.5 работает под управлением NETWORK. Используя сертификаты MMC, добавьте «NETWORK SERVICE» для полного доверия к сертификату в «Local Computer\Personal».
  • Веб-сайт IIS 7.5 работает под учетной записью пользователя локального компьютера «MyIISUser». Используя сертификаты MMC, добавьте «MyIISUser» (новую учетную запись пользователя локального компьютера) в Full Trust для сертификата в «Local Computer\Personal».

Обновление на основе комментария @Phil Hale:

Опасайтесь, если вы находитесь в домене, ваш домен будет выбран по умолчанию в поле «from location». Обязательно измените это на «Локальный компьютер» . Измените местоположение на «Локальный компьютер» , чтобы просмотреть идентификаторы пула приложений.

Примечание о предоставлении разрешений через MMC, Certs, Select Cert, щелкните правой кнопкой мыши, все задачи, «Управление приватными ключами»

Управление приватными ключами осуществляется только в списке меню для личного. Итак, если вы поставили свой сертификат в Trusted People и т.д. вам не повезло.

Мы нашли способ вокруг этого, который сработал для нас. Перетащите сертификат в «Личный», выполните действие «Управление секретными ключами», чтобы предоставить разрешения. Не забудьте установить использование встроенных модулей типа объекта и использовать локальный компьютер, а не домен. Мы предоставили права пользователю DefaultAppPool и оставили его на этом.

Как только вы закончите, перетащите сертификат обратно туда, где вы его первоначально имели. Presto.

Илон Маск рекомендует:  Псевдокласс default
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL
mk-user-certs