Search code examples
c#.netx509certificate2

Send rest request with attached pfx certificate


I'm trying to consume an API that uses a certificate as an authentication method.

I tried two methods but I get the same issue:

The request was aborted: Unable to create a secure SSL/TLS channel.

Method 1:

var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
string certificatePath = @"certificates/certificate.pfx";
string pass = "password";

handler.ClientCertificates.Add(new X509Certificate2(certificatePath, pass));

var client = new HttpClient(handler);
var dataToAuth = new StringContent(body, Encoding.UTF8, "application/json");
var request = client.PostAsync("https://api.com/oauth/v2/token", dataToAuth).GetAwaiter().GetResult();

var response = request.Content.ReadAsStringAsync().GetAwaiter().GetResult();
return response;

Method 2:

var client = new RestClient("https://api.com/oauth/v2/token");
client.Timeout = -1;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var certFile = Path.Combine(@"certificates/", "certificate.pfx");
X509Certificate2 certificate = new X509Certificate2(certFile, "password");
client.ClientCertificates = new X509CertificateCollection() { certificate };
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
string jsonPreInscription = new JavaScriptSerializer().Serialize(body);
request.AddParameter("application/json", jsonPreInscription, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
if (response.StatusCode == HttpStatusCode.OK)
{
    return response;
}

return response;

I really can't see the problem and i tried also the two methods using the .cer file and it's key.

I would be greatful for any ideas.


Solution

  • so the problem was the method used to hash the certificate itself. aperantly the version of the certificate needs the X509Certificate method instead of the X509Certificate2 i was using(for my case).

    here is the updated working code :

                var handler = new HttpClientHandler();
                handler.ClientCertificateOptions = ClientCertificateOption.Manual;
                ServicePointManager.Expect100Continue = true;
    
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
                string certificatePath = @"certificates/certificate.pfx";
                string pass = "password";
    
                handler.ClientCertificates.Add(new X509Certificate(certificatePath, pass));
    
                var client = new HttpClient(handler);
                var dataToAuth = new StringContent(body, Encoding.UTF8, "application/json");
                var request = client.PostAsync("https://api.com/oauth/v2/token", dataToAuth).GetAwaiter().GetResult();
    
                var response = request.Content.ReadAsStringAsync().GetAwaiter().GetResult();
    

    I hope no one suffers as i did to figure this out :)