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

Как заставить клиента WCF отправлять сертификат клиента?

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

  • Для этой службы требуются сертификаты клиентов. У меня есть сертификат, подписанный тем же CA, что и сертификат сервера.
  • Я знаю, что URL доступен, так как я могу попасть в Internet Explorer. IE вызывает окно "выбрать сертификат", и если я его выберу (и проигнорирую ошибку server-host-name-do-not-match-certificate), он продолжит работу и даст мне ошибку 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, я мог бы не заметить подсказки относительно того, что происходит. Здесь, однако, это то, что я вижу:

  • C → S Client Hello
    • Содержит такие вещи, как случайное число, дата/время, поддержка cypher и т.д.
  • S → Сервер C Привет, сертификат, запрос сертификата, сервер Hello Done
    • Содержит сертификат сервера и запрос для сертификата клиента
  • Сертификат C → S, обмен ключами клиентов, изменение спецификации шифрования, сообщение с зашифрованным рукопожатием
    • ЗДЕСЬ ИНТЕРЕСНАЯ ЧАСТЬ. Первая часть этого пакета - это рукопожатие с сертификатом, где я предполагаю, что будет сертификат клиента, но сертификатов нет (Certificates Length: 0).
  • S → C Alert (Уровень: Fatal, Описание: 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-соединения?

4b9b3361

Ответ 1

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

<httpsTransport useDefaultWebProxy="false" />

:

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

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

Ответ 2

На сервере должно было быть CertificateRequest, назвав приемлемые типы сертификатов и ЦС. Если ваш сертификат не соответствует тем, он не будет отправлен.

Ответ 3

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

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

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

Это может быть добавлено либо в клиентский код, либо путем размещения его в IEndpointBehavior