I just created an empty .NET Core Console application, from which I want to reach a 3rd party API via HttpClient. The endpoint requires an SSL certificate, as well as an APIKey and Username in the request's headers. I've setup the call in Postman (and Visual Studio Code's REST Client extension) for testing purposes, and I'm getting a 200 back, with the expected payload. However, when using HttpClient (or RestSharp, for that matter), I'm getting the following exception:
The SSL connection could not be established, see inner exception. The remote certificate is invalid according to the validation procedure.
Here's my code (mocked in the example the url, apikey, username, certificate base64 string and the proxy my company uses):
using (var request = new HttpRequestMessage(HttpMethod.Get, "validUrl"))
{
var certi = "..."; // base64 string
var bytes = Convert.FromBase64String(certi);
var pfxCert = new X509Certificate2Collection();
pfxCert.Import(bytes, null, X509KeyStorageFlags.MachineKeySet);
request.Headers.Add("apikey", "validApiKey");
request.Headers.Add("username", "myUser");
var handler = new HttpClientHandler();
handler.ClientCertificates.AddRange(pfxCert);
handler.Proxy = new WebProxy("myValidCorporateProxy", false);
using (var httpClient = new HttpClient(handler))
{
using (var response = httpClient.SendAsync(request).Result)
{
var content = response.Content.ReadAsStringAsync().Result;
}
}
}
I also tried to play around with ServicePointManager, with no luck:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11; // tested with Tls, Tls11, Tls12
ServicePointManager.Expect100Continue = true;
Maybe I'm failing to convert the .pfx into a base64 encoded string? I've used to following PowerShell commands:
$fileContentBytes = get-content 'C:\Users\myUser\Desktop\certificate.pfx' -Encoding Byte
[System.Convert]::ToBase64String($fileContentBytes) | Out-File ‘C:\Users\myUser\Desktop\certificate-string.txt’
UPDATE: Using the answer from this question: .net core API Post exception gives NativeErrorCode 12175
It works:
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
But I feel like this isn't too safe of a workaround (bypassing the validation), isn't it?
UPDATE2 When hitting ServerCertificateCustomValidationCallback, I can apparently see a more useful error: System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch
So, I'm assuming something is either wrong with my certificate, or the server's (but Postman somehow ignores this)? Maybe I should take it up with the 3rd party.