Фон
Конечная точка API основана на HTTPS и требует сертификата клиента (формат PKCS12 с паролем).
Postman Testing показывает успешные ответы (200 OK) для некоторых конечных точек, но 500 внутренний сервер с помощью «Сертификат Expred». SSLHandshakeException: Handshake_failure, предлагая проблему совместимости.
Поставщик услуг утверждает, что все работает нормально. Сделано < /strong>
с использованием httpclient с servercertificatecustomvalidationcallback
настроить httpclienthandler, чтобы игнорировать ошибки SSL: < /p>
Код: Выделить всё
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(new X509Certificate2("path/to/certificate.p12", "password"));
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
using var client = new HttpClient(handler);
var response = await client.PostAsync("https://api.endpoint", new StringContent("{}", Encoding.UTF8, "application/json"));
< /code>
Результат: соединение SSL не может быть установлено, см. Внутреннее исключение. Внутреннее исключение: аутентификация не удалась, см. Внутреннее исключение. Глубокое внутреннее исключение: получил неожиданное сообщение или сообщение имеет неправильный формат.System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11;
< /code>
в сочетании с вышеуказанной настройкой httpclient, но та же самая ошибка SSL сохранялась. < /p>
[b] Использование httpwebrequest < /strong>
Попытка альтернативы: < /p>
var request = (HttpWebRequest)WebRequest.Create("https://api.endpoint");
request.ClientCertificates.Add(new X509Certificate2("path/to/certificate.p12", "password"));
request.Method = "POST";
request.ContentType = "application/json";
request.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
using (var stream = request.GetRequestStream())
{
byte[] data = Encoding.UTF8.GetBytes("{}");
stream.Write(data, 0, data.Length);
}
using var response = (HttpWebResponse)request.GetResponse();
с использованием RestSharp [/b]
Пробое с последней версией RestSharp (например, 108.x) через nuget:
Код: Выделить всё
var options = new RestClientOptions("https://api.endpoint")
{
RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true,
ClientCertificates = new X509CertificateCollection { new X509Certificate2("path/to/certificate.p12", "password") },
MaxTimeout = 30000
};
using var client = new RestClient(options);
var request = new RestRequest { Method = Method.Post };
request.AddHeader("Content-Type", "application/json");
request.AddJsonBody(new { contractId = "" }); // Example with obscured data
var response = client.Execute(request);
< /code>
Результат: статус: 0 - 0, issuccessful: false, errormessage: соединение SSL не может быть установлено, см. Внутреннее исключение. Первоначально не было доступно детали внутренних исключений, но добавление журнала исключений показала ту же ошибку SSL.using var client = new TcpClient("api.endpoint", 443);
using var sslStream = new SslStream(client.GetStream(), false, (sender, cert, chain, errors) => true, null);
sslStream.AuthenticateAsClient("api.endpoint", new X509CertificateCollection { new X509Certificate2("path/to/certificate.p12", "password") }, SslProtocols.Tls12 | SslProtocols.Tls11, false);
// Send HTTP request manually
Пример полный код
Код: Выделить всё
using System;
using RestSharp;
using System.Security.Cryptography.X509Certificates;
using System.Text.Json;
class Program
{
static void Main(string[] args)
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11;
string certPath = "path/to/certificate.p12"; // Replace with actual path
string certPassword = "password"; // Replace with actual password
string apiUrl = "https://IP/solar-bridge-ext/ext/json-services/getContractBalance"; // Replace with actual endpoint
try
{
var certificate = new X509Certificate2(certPath, certPassword);
Console.WriteLine("Client certificate loaded successfully: " + certificate.Subject);
var options = new RestClientOptions(apiUrl)
{
RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => { Console.WriteLine($"Errors: {sslPolicyErrors}"); return true; },
ClientCertificates = new X509CertificateCollection { certificate },
MaxTimeout = 30000
};
using var client = new RestClient(options);
var request = new RestRequest { Method = Method.Post };
request.AddHeader("Content-Type", "application/json");
request.AddJsonBody(new { contractId = "" });
Console.WriteLine("Sending request...");
var response = client.Execute(request);
Console.WriteLine($"Status: {(int)response.StatusCode} - {response.StatusCode}");
Console.WriteLine($"IsSuccessful: {response.IsSuccessful}");
Console.WriteLine($"ErrorMessage: {response.ErrorMessage}");
if (response.ErrorException != null)
{
Console.WriteLine($"Exception: {response.ErrorException.Message}");
if (response.ErrorException.InnerException != null)
Console.WriteLine($"Inner Exception: {response.ErrorException.InnerException.Message}");
}
Console.WriteLine("Response: " + (response.Content ?? "No data"));
var responseData = JsonSerializer.Deserialize(response.Content ?? "{}");
if (responseData?.Result?.ResultCode == 0)
Console.WriteLine("Data retrieved successfully.");
else
Console.WriteLine($"Error: {responseData?.Result?.ResultMessage ?? "No message"}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
if (ex.InnerException != null)
Console.WriteLine($"Inner Error: {ex.InnerException.Message}");
}
}
public class SampleResponse { public Result? Result { get; set; } }
public class Result { public int ResultCode { get; set; } public string? ResultMessage { get; set; } public object[]? Payload { get; set; } }
}
Сервер может использовать устаревшую конфигурацию, возможно, TLS 1.0, который .NET 7 может не поддерживать по умолчанию. Context < /strong> < /p>
. НЕТ ВЕРСИЯ: 7.0.
Клиентский сертификат действителен и успешно загружается во всех случаях.
Запросы отправляются с пустым телом JSON ({}) или конкретными данными (например, {"ContractId": }) как требуется.
Вопрос
Как я могу успешно подключиться к этой API, несмотря на SS, несмотря на SS, несмотря на SS, несмотря на SS. Несмотря на то, что AP, несмотря на SS, несмотря на SS, несмотря на SS. Есть ли способ заставить конкретную версию TLS (например, TLS 1.0) или дальше обход проверки сертификата сервера? В качестве альтернативы, может ли это быть проблемой на стороне сервера, требующей действий от поставщика API, тем более что они утверждают, что все работает на их конце? Любые предложения для отладки или альтернативных библиотек будут оценены. Что все работает на их конце, тот факт, что VPN не помог, и полный пример кода с скрытыми конфиденциальными данными. Вы можете скопировать этот текст, вставить его в переполнение стека и отправить его. Если вы получаете ответы или вам нужно обновить его с помощью новых выводов, дайте мне знать, и я помогу в его усовершенствовании! /> httpwebrequest с обходом сертификатов. < /p>
RestSharp с отключенной проверкой SSL. < /p>
SSLStream низкого уровня для ручной обработки SSL. /> Что я ожидал:
Успешное подключение к HTTPS (например, от ответов Postman 200 OK) для извлечения данных с конечных точек API. Вместо этого я последовательно сталкивался с отказом от рукопожатия SSL, предлагая протокол/несоответствие сертификата или проблему с сервером. Не удается полностью. < /p>
Провайдер настаивает на том, что их настройка функциональная, но доказательства указывают на проблемы совместимости. < /p>
Цель:
Минимальный рабочий пример для отладки или обхода проблемы SSL или подтверждения.>
Подробнее здесь: https://stackoverflow.com/questions/796 ... ed-despite