Search code examples
c#authenticationsslssl-certificateclient

SSL Client Authentication with certificate using c#


I need to create a c# application that has to send API request to a server using SSL. I need to create the Client authentication. I already have the server CA certificate, the client certificate (cer), the client private key (pem) and passphrase. I can't find an example on how to create the client connection. Can someone suggest me where to start with a small code well explained? In my hand I have the client certificate (PEM), the Client Provate Key and the Passphrase for the Client Key. I have no idea where to start to write the code to send a request to the server


Solution

  • Some time ago I've created this POC for client authentication with certificate in .Net Core. It uses idunno.Authentication package that is now build-in in .Net Core. My POC probably is bit outdated now, but it can be a good starting point for you.

    First create an extension method to add certificate to HttpClientHandler:

    public static class HttpClientHandlerExtensions
    {
        public static HttpClientHandler AddClientCertificate(this HttpClientHandler handler, X509Certificate2 certificate)
        {
            handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            handler.ClientCertificates.Add(certificate);
    
            return handler;
        }
    }
    

    Then another extension method to add certificate to IHttpClientBuilder

        public static IHttpClientBuilder AddClientCertificate(this IHttpClientBuilder httpClientBuilder, X509Certificate2 certificate)
        {
            httpClientBuilder.ConfigureHttpMessageHandlerBuilder(builder =>
            {
                if (builder.PrimaryHandler is HttpClientHandler handler)
                {
                    handler.AddClientCertificate(certificate);
                }
                else
                {
                    throw new InvalidOperationException($"Only {typeof(HttpClientHandler).FullName} handler type is supported. Actual type: {builder.PrimaryHandler.GetType().FullName}");
                }
            });
    
            return httpClientBuilder;
        }
    

    Then load the certificate and register HttpClient in HttpClientFactory

            var cert = CertificateFinder.FindBySubject("your-subject");
            services
                .AddHttpClient("ClientWithCertificate", client => { client.BaseAddress = new Uri(ServerUrl); })
                .AddClientCertificate(cert);
    

    Now when you will use client created by factory it will automatically send your certificate with the request;

    public async Task SendRequest()
    {
        var client = _httpClientFactory.CreateClient("ClientWithCertificate");
        ....
    }