The server owner informed me that I need to perform double-sided certificate authentication. When I try to post a message through HttpClient using the same certificate that I emailed to the owner, an exception is thrown:
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred while sending. ---> System.IO.IOException: Authentication failed because the remote party closed the transport stream.
The post message run in ‘curl’ was succesfull with code 500. The program is simple and works without any problems when built with .NET Core, but it does not work when built with .NET Framework.
Program runs with no issues on Windows 11, but I am trying to run the program on Windows 10 and have this problems. I’ve installed the latest updates. I am building it with .NET Framework 4.8.
Wireshark shows that after the ‘Server Hello’, the client does not acknowledge the certificates, and the ‘Certificate, Client Key Exchange’ indicates that no certificates were established.
ServicePointManager.ServerCertificateValidationCallback = myServerCertificateValidationCallback2;//(sender, certificate, chain, sslPolicyErrors) => true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Task.Run(async () =>
{
try
{
using (var certificate = new X509Certificate2(file, pass, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet))
{
byte[] certBytes = certificate.Export(X509ContentType.Pfx);
var certificate2 = new X509Certificate2(certBytes);
using (var request = new HttpRequestMessage(HttpMethod.Post, requestUri))
{
var clientHandler = new WebRequestHandler();
clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
clientHandler.ClientCertificates.Add(certificate2);
var client = new HttpClient(clientHandler, true);
var response = await client.SendAsync(request, CancellationToken.None).ConfigureAwait(false);
Console.WriteLine(response.StatusCode);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
await Task.CompletedTask;
}
}).GetAwaiter().GetResult();
Console.ReadKey();