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

Взаимная аутентификация SSL с использованием WCF: нет сертификата и сертификата CertificateVerify в фазе подтверждения

Я работаю над сервисом WCF, который должен использоваться клиентом, который не разработан мной, а также не .NET(возможно, Java).

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

Моя проблема в том, что я не могу получить правильную конфигурацию WCF, так что проверка подлинности сертификата клиента работает правильно. Я ожидаю, что, как часть рукопожатия TLS, сервер также включает Certificate Request, как показано ниже:

enter image description here

После этого клиент должен ответить "Свидетельством сертификата" между прочим:

enter image description here

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

<bindings>
  <customBinding>
    <binding name="CarShareSecureHttpBindingCustom">
      <textMessageEncoding messageVersion="Soap11" />
      <security authenticationMode="MutualSslNegotiated"/>
      <httpsTransport requireClientCertificate="true" />
    </binding>
  </customBinding>
</bindings>

...

<serviceBehaviors>
  <behavior name="ServiceBehavior">
    <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
    <serviceDebug includeExceptionDetailInFaults="false" httpHelpPageEnabled="false" />
    <serviceCredentials>
      <serviceCertificate findValue="..." storeLocation="LocalMachine" x509FindType="FindByIssuerName" storeName="My" />
      <clientCertificate>
        <certificate findValue="..." storeName="My" storeLocation="LocalMachine" x509FindType="FindByIssuerName"/>
      </clientCertificate>
    </serviceCredentials>
  </behavior>
</serviceBehaviors>

Часть приветствия сервера Hello приветствует это для всех конфигураций службы, которые я пробовал, без CertificateRequest. enter image description here

Другие вещи, которые я должен упомянуть:

  • Служба самообслуживания и прослушивание нестандартного порта (не 443). SSL-сертификат сервера привязан к этому порту.
  • Я также попробовал basicHttpBinding и wsHttpBidning с режимом безопасности, установленным на Transport, и аутентификацию клиента, установленную на Certificate, без каких-либо результатов (фактически на самом деле).

Любые идеи будут оценены.

4b9b3361

Ответ 1

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

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

Платформы, на которых я смог воспроизвести и исправить это: Windows 8.1 x64 и Windows Server 2008 R2 Standard.

Как я уже упоминал, моя проблема заключалась в том, что я не смог настроить безопасность WCF, чтобы для службы требовались клиентские сертификаты. Общая путаница, которую я заметил при поиске решения, заключается в том, что многие люди считают, что клиент может отправить сертификат, если он есть, без ответа. Это, конечно, не тот случай - сервер должен сначала запросить его, и, кроме того, указать, какие CAs разрешены через ответ CertificateRequest.

Подводя итог, моя ситуация была:

  • Служба самообслуживания.
  • Служба работает на HTTPS, на нестандартном порту (не 443, а 9000).

Это означало, что мне пришлось создать привязку SSL-сертификата для порта 9000 с помощью netsh.exe http add sslcert. Ну, привязка была создана, но был улов. Я только нашел проблему после запуска netsh http show sslcert только для проверки моей привязки:

 IP:port                      : 0.0.0.0:9000
 Certificate Hash             : ...
 Application ID               : ...
 Certificate Store Name       : MY
 Verify Client Certificate Revocation : Enabled
 Verify Revocation Using Cached Client Certificate Only : Disabled
 Usage Check                  : Enabled
 Revocation Freshness Time    : 0
 URL Retrieval Timeout        : 0
 Ctl Identifier               : (null)
 Ctl Store Name               : (null)
 DS Mapper Usage              : Disabled
 -->Negotiate Client Certificate : Disabled

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

Повторное связывание с приведенным ниже выражением решает проблему:

netsh.exe http add sslcert ipport=0.0.0.0:9000 certhash=... appid=... certstorename=MY verifyclientcertrevocation=Enable VerifyRevocationWithCachedClientCertOnly=Disable UsageCheck=Enable clientcertnegotiation=Enable

Перед проверкой привязок я попробовал провести простую службу WCF в IIS и включить проверку подлинности сертификата клиента. Было очень любопытно видеть, что, хотя IIS не выдал CertificateRequest, он по-прежнему не справился с 403.7. Даже IIS не создавал привязку с соответствующими параметрами.

В любом случае, теперь это работает, и вы можете это исправить.

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

<customBinding>
  <binding name="CustomHttpBindingCustom" receiveTimeout="01:00:00">
    <textMessageEncoding messageVersion="Soap11" />
    <security authenticationMode="SecureConversation" requireSecurityContextCancellation="true">
      <secureConversationBootstrap allowInsecureTransport="false" authenticationMode="MutualSslNegotiated" requireSecurityContextCancellation="true"></secureConversationBootstrap>
    </security>
    <httpsTransport requireClientCertificate="true" />
  </binding>
</customBinding>