Перевести cURL на RestSharp (не удалось создать безопасный канал SSL/TLS)

Я работаю над интеграцией со сторонним поставщиком, который предоставляет пример кода для использования с cURL. Мне удалось успешно подключиться с помощью cURL с помощью следующей команды:

curl -k -d "grant_type = client_cert" --basic -u "myUserName: myPassword" -H "Тип содержимого: application / x-www-form-urlencoded" --cert c: \ certs \ myCert.pem https://vendorurl/method

Читая документы cURL, я полагаю, что все переключатели переводятся на:

  • -k: небезопасно (продолжить, даже если соединение не защищено)
  • -d: данные. Также указывает, что это ПОЧТА.
  • --basic: базовая аутентификация
  • -u имя пользователя / пароль
  • -H дополнительный заголовок
  • --cert: пройти сертификат

Я перепробовал много (!) Разных советов, которые нашел в Интернете, поэтому есть некоторые строки кода, которые могут оказаться ненужными. Я попытался указать, где я интерпретировал переключатели cURL на C# в моих комментариях к коду.

        //Not sure if these are needed or not.
        ServicePointManager.Expect100Continue = true;
        ServicePointManager.CheckCertificateRevocationList = false;

        //allow every possible protocol for now just to eliminate the protocol as the source of the problem
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;

        //this should be the equivalent of cURL's "-k" (insecure) switch.
        ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;

        var certificatePath = ConfigurationManager.AppSettings.GetValue("myPath");
        var clientKey = "myKey";
        var clientSecret = "mySecret";

        var url = "https://vendorUrl/method";

        //create the request
        var request = new RestRequest(Method.POST);

        ////this should be the equivalent of cURL's -d (data) switch.  no idea if this is done correctly.  I have also tried adding this as "AddJsonBody()"
        var body = "grant_type=client_cert";
        request.AddBody(body);

        //this should be the equivalent of cURL's "-H" (header) switch
        request.AddHeader("Content-Type", "application/x-www-form-urlencoded");

        //Import certificate
        var certificates = new X509Certificate();
        certificates.Import(certificatePath);

        var client = new RestClient
        {
            BaseUrl = new Uri(url),
            //this should be the equivalent of cURL's "--cert" switch
            ClientCertificates = new X509CertificateCollection { certificates },
            //this should be the equivalent of cURL's "--basic" (Basic Auth) switch and the "-u" switch
            Authenticator = new HttpBasicAuthenticator(clientKey, clientSecret)
        };

        var response = client.Execute(request);

Я получаю сообщение об ошибке: "Запрос был прерван: не удалось создать безопасный канал SSL/TLS".

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

Я действительно не знаю, как проанализировать вывод трассировки, но одно из последних сообщений в трассировке выглядит как проблема:

Информация System.Net: 0: [9232] InitializeSecurityContext(количество входных буферов =2, длина внешнего буфера =0, возвращенный код =IllegalMessage).

1 ответ

Решение

В моем случае мне пришлось установить сертификат на локальный компьютер / сервер, чтобы заставить его работать. Мне не понятно, почему cURL работает без установленного сертификата.

Сертификат, который я должен был установить, имел расширение.p12. Таким образом, в коде я загрузил файл.pem, который является производным от файла.p12. Я не утверждаю, что понимаю почему.

Переключившись на HttpClient, я смог избежать загрузки файла.pem, добавив:

            var handler = new WebRequestHandler();
            handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
            var httpClient = new HttpClient(handler);

Мне не удалось найти RestSharp/WebRequest, эквивалентный ClientCertificateOptions.

Другие вопросы по тегам