Сбой при отладке HTTPS WebRequest

#c# #.net #https #httpwebrequest #x509certificate

#c# #.net #https #httpwebrequest #x509certificate

Вопрос:

Я пишу небольшую программу, которая отправит GET-запрос на сервер, используя HTTPS и класс HttpWebRequest. Сервер (очевидно) имеет сертификат сервера. Он также ожидает, что клиент предоставит сертификат.

Однако при выполнении запроса я получаю System.Net.WebException, в котором указано, что не удалось установить безопасное соединение TLS / SSL. Я быстро обнаружил, что сертификат сервера недействителен. Предполагая, что это было причиной исключения, я попытался принять недействительный сертификат (обновление сертификата, к сожалению, не вариант), используя приведенный ниже код:

 ServicePointManager.ServerCertificateValidationCallback  = delegate {
    return true;
};
  

Однако это не решило проблему.

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

Я хотел бы получить советы о том, как отладить проблему такого рода. К сожалению, у меня нет доступа к серверу или его журналам.

Ниже приведены важные части кода:

 ServicePointManager.ServerCertificateValidationCallback  = delegate {
    return true;
};
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); // url is an HTTPS URL.
X509Certificate clientCert = new X509Certificate("certificate.crt", "password");
req.ClientCertificates.Add(clientCert);
WebResponse resp = req.GetResponse(); // This fails!
  

Комментарии:

1. Черт возьми, вы могли бы попробовать запустить Fiddler (www.fiddler2.com ) при использовании вашего приложения. В подобных случаях Fiddler обычно показывает более наглядные сообщения об ошибках.

Ответ №1:

Наложите на него некоторую трассировку! Трассировки — ваш лучший друг при отладке этих вещей. Однажды у меня был один клиент, который не мог подключиться к нашей службе с поддержкой SSL. Используя трассировку, я обнаружил, что кто-то переместил системные часы после истечения срока действия нашего сертификата. Но я отвлекся.

Включите все применимые источники трассировки и посмотрите, появится ли что-нибудь интересное в журналах.

Есть старый (2005), но отличный пост Дургапрасада Горти, который вы должны проверить. Он покажет вам, какие именно источники следует добавить, и в нем он также показывает некоторые трассировки SSL, используя пользовательский обратный вызов проверки.

Пример app.config из того же поста в блоге:

 <?xml version="1.0" encoding="UTF-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.Net">
        <listeners>
          <add name="MyTraceFile"/>
        </listeners>
      </source>
    </sources>

    <sharedListeners>
      <add
      name="MyTraceFile"
      type="System.Diagnostics.TextWriterTraceListener"
      initializeData="System.Net.trace.log"
    />
    </sharedListeners>

    <switches>
      <add name="System.Net" value="Verbose" />
    </switches>

  </system.diagnostics>
</configuration>
  

Надеюсь, это предоставит вам дополнительные данные.

Комментарии:

1. Ссылка в сообщении теперь не работает, хорошей альтернативой может быть: learn.microsoft.com/en-us/dotnet/framework/network-programming /…

Ответ №2:

Некоторые мысли:

  1. TLS определяет некоторые коды ошибок и предупреждения. Библиотеки SSL / TLS часто предоставляют этот код при возникновении исключения. Может быть, вы могли бы найти эту информацию в журнале сервера.

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

  3. Если ожидается, что клиент будет использовать сертификат для аутентификации, сервер должен отправить имена принятых корневых сертификатов. Мой предыдущий пункт также справедлив и здесь, если отсутствуют некоторые промежуточные сертификаты, невозможно построить цепочку между своим сертификатом и корневым, отправленным сервером. Клиент не находит подходящий сертификат (поскольку закрытый ключ недоступен) — еще одна возможная проблема.

Комментарии:

1. Jcs: пункт 3 вполне может быть моей проблемой (у меня еще не было возможности посмотреть, что говорят мне трассировки). Как бы мне это исправить? Как бы мне добавить корневой сертификат, который будет проверяться стеком SSL?

2. Определенно, то, как настроен центр сертификации клиента, зависит от серверного приложения или, по крайней мере, от модуля, обрабатывающего SSL / TLS.

Ответ №3:

Я согласен с решением Маркуса выше. У меня однажды была похожая проблема, и я обнаружил, что лучшее, что можно сделать, это получить это исключение в отладчике.

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

В случае, о котором я думаю, мне пришлось просмотреть 4 или 5 InnerExceptions, прежде чем я добрался до сообщения, в котором конкретно говорилось, что было не так.

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

Надеюсь, это поможет.