Как заставить клиента WCF отправить сертификат клиента? - PullRequest
13 голосов
/ 03 ноября 2010

Я пытаюсь получить доступ к общедоступной веб-службе SOAP (не WCF) по протоколу https и получаю сообщение об ошибке, которого раньше никогда не было. Во-первых, вот факты:

  • Для этой услуги требуются клиентские сертификаты. У меня есть сертификат, подписанный тем же центром сертификации, что и сертификат сервера.
  • Я знаю, что URL доступен, так как я могу нажать его в Internet Explorer. IE вызывает окно «выбрать сертификат», и если я его выберу (и игнорирую ошибку сервера-хоста-имя-не-совпадать-сертификат), оно продолжится и выдаст мне ошибку HTTP 500.
  • Если я открываю сайт в Chrome, после выбора сертификата и игнорирования ошибки я получаю обычное сообщение об ошибке WSA Action = null.
  • Если я открою сайт в FireFox, после игнорирования ошибки, я получу страницу о том, как сервер не может проверить мой сертификат. Он никогда не просил меня выбрать один, так что это имеет смысл.

Теперь исключение:

Error occurred while executing test 12302: System.ServiceModel.Security.SecurityNegotiationException: Could not establish secure channel for SSL/TLS with authority 'ihexds.nist.gov:9085'. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
   at System.Net.HttpWebRequest.GetResponse()
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

Я проследил взаимодействие с WireShark, но, поскольку я не являюсь экспертом в протоколе TLS, я мог упустить подсказки о том, что происходит. Вот что я вижу:

  1. C -> S Client Hello
    • Содержит такие вещи, как случайное число, дата / время, поддерживаемые наборы шифров и т. Д.
  2. S -> C Сервер Hello, Сертификат, Запрос сертификата, Сервер Hello Done
    • Содержит сертификат сервера и запрос сертификата клиента
  3. C -> S сертификат, обмен ключами клиента, спецификация изменения шифра, зашифрованное рукопожатие
    • ЗДЕСЬ ИНТЕРЕСНАЯ ЧАСТЬ - Первая часть этого пакета - рукопожатие сертификата, где я предполагаю, что сертификат клиента будет, но сертификаты отсутствуют (Длина сертификатов: 0).
  4. S -> C Alert (Уровень: Фатальный, Описание: Bad Certificate)
    • Ну да, сертификат не был отправлен.

Моя привязка настроена следующим образом:

<binding name="https_binding">
    <textMessageEncoding />
    <httpsTransport useDefaultWebProxy="false" />
</binding>

Мое поведение настроено следующим образом:

<behavior name="clientcred">
    <clientCredentials>
        <clientCertificate findValue="69b6fbbc615a20dc272a79caa201fe3f505664c3" storeLocation="CurrentUser" storeName="My" x509FindType="FindByThumbprint" />
        <serviceCertificate>
            <authentication certificateValidationMode="None" revocationMode="NoCheck" />
        </serviceCertificate>
    </clientCredentials>
    <messageInspector />
</behavior>

Моя конечная точка настроена на использование как привязки, так и поведения. Почему WCF отказывается отправлять сертификат при создании соединения https?

Ответы [ 3 ]

9 голосов
/ 08 ноября 2010

Я решил проблему, но я не понимаю, почему это изменение конфигурации исправило это.Я изменил эту строку:

<httpsTransport useDefaultWebProxy="false" />

на эту:

<httpsTransport useDefaultWebProxy="false" requireClientCertificate="true" />

и волшебным образом она начала работать.Я понял, что «ручка» requireClientCertificate предназначена для серверной части, поэтому я не пробовал ее во время споров.Видимо, я был не прав.

2 голосов
/ 04 ноября 2010

Должен был быть CertificateRequest с сервера с указанием допустимых типов сертификатов и CA. Если ваш сертификат не соответствует этим сертификатам, он не будет отправлен.

0 голосов
/ 04 ноября 2010

Может возникнуть проблема при согласовании используемого протокола безопасности. В частности, я думаю, что серверу может не понравиться WCF, пытающийся использовать TLS 1.0.

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

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3

Это можно добавить либо в коде клиента, либо поместив его в IEndpointBehavior

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