Подтвердить что ты не робот

Не удалось создать защищенный канал SSL/TLS для winforms, но не в asp.net

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

        service = new MyReferencedWebService();

        X509Certificate2 cert = new X509Certificate2();

        var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Mycert.cer");
        var bytes = new byte[stream.Length];

        stream.Read(bytes, 0, bytes.Length);

        cert.Import(bytes, MYPASSWORD, X509KeyStorageFlags.DefaultKeySet);

        service.ClientCredentials.ClientCertificate.Certificate = cert;

и моя конфигурация выглядит так:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="RecordGeneratorWebServiceSoapHttp">
                <security mode="Transport">
                    <transport clientCredentialType="Certificate" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://mywebserviceurl"
            binding="basicHttpBinding" bindingConfiguration="RecordGeneratorWebServiceSoapHttp"
            contract="MyService.RecordGeneratorWebServiceInterface"
            name="RecordGeneratorWebServicePort" />
    </client>
</system.serviceModel>

Если я создаю простой winforms.exe и использую вышеуказанный код, я получаю ответ от своего веб-сервиса. Однако, если я ставлю этот же код в ASP.NET, я получаю следующее:

Запрос был прерван: не удалось создать безопасный канал SSL/TLS.

Как это сделать в ASP.NET?

EDIT: Я должен добавить. Клиентский сертификат, который я использую, привязан к смарт-карте и требует ввода PIN-кода для использования. Не уверен, что это имеет значение или нет.

Когда клиент входит в приложение, он запрашивает у них свой PIN-код сертификата. В этом случае у них есть карточка CAC, вставленная в считыватель CAC. Может быть, я могу каким-то образом использовать Request.ClientCertificate?

4b9b3361

Ответ 1

Каков ваш план здесь? Другими словами:

Кто будет вводить ПИН? Кто собирается вставлять смарт-карту?

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

Ваш лучший способ действий:

A) Запросить "сертификат сервера" (не смарт-карту), который может использоваться в качестве сертификата клиента для канала между веб-сервером ASP.NET и целевой веб-службой.

или

B) Перепроектируйте решение таким образом, чтобы клиенты (люди, у которых есть смарт-карты и контакты) напрямую подключались к защищенному веб-сервису с помощью смарт-карты и PIN-кода.

Ответ 2

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

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

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

Ответ 3

Конфигурация клиента WCF

На всякий случай, убедитесь, что адрес вашей конечной точки имеет форму:

"https://hostname[:port]/ServiceDirectory/MyService.svc"

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

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="RecordGeneratorWebServiceSoapHttp">
                <security mode="Transport">
                    <transport clientCredentialType="Certificate" proxyCredentialType="None" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://hostname[:port]/ServiceDirectory/MyService.svc"
            binding="basicHttpBinding" bindingConfiguration="RecordGeneratorWebServiceSoapHttp"
            contract="MyService.RecordGeneratorWebServiceInterface"
            name="RecordGeneratorWebServicePort" />
    </client>
</system.serviceModel>

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

Если ваша служба размещена в IIS 6.0 или IIS 7.0, вы должны настроить IIS, на котором размещена ваша служба WCF, для принятия клиентских сертификатов.

Ваше приложение asp.net является клиентом WCF. См. эту страницу по использованию сертификата смарт-карты и Защита служб WCF с сертификатами.

Вам также понадобится сертификат SSL сервера, который будет установлен в IIS, где вы размещаете свой сервис WCF для поддержки HTTPS.

Конфигурация службы WCF

Конечная точка службы должна включать защищенную привязку HTTP, а также поведение службы, чтобы включить httpsGetEnabled и отключить httpGetEnabled:

<service name="MyService">
   <endpoint address="" contract="MyServiceInterface" binding="basicHttpBinding" bindingConfiguration="secureHttpBinding"/>
</service>

<serviceBehaviors>
  <behavior name="">
    <serviceMetadata  httpGetEnabled="false" httpsGetEnabled="true" />
  </behavior>
</serviceBehaviors>

<basicHttpBinding>
   <binding name="secureHttpBinding">
      <security mode="Transport">
         <transport clientCredentialType="Certificate" proxyCredentialType="None"/>
      </security>
   </binding>
</basicHttpBinding>