none
C# Making a request with a client certificate (p12 <--> pem) to a Java/Unix based web service (Resin web server) RRS feed

  • Question

  • Hi,

    For a client I'm developing a proxy class in C# for easy communication with a web service that's hosted on a Resin web server, which apparently is a Java/Unix environment.

    For authentication with the web service I need to pass my client certificate with every request I make and that's were the trouble starts

    I requested a client certificate from COMODO which I installed on my local machine. I exported this certificate to a p12 file with a private key.

    To make myself known on the web server I had to upload a pem file to the web server so I used openssl to convert my p12 file to a pem file with a pass phrase and uploaded this to server which got accepted, contrary to my p12 file.

    The manual of the web service supplies a code example making use of curl. I have to post three parameters and a xml file to a specified URL. My code looks as follows:

    curl -E clientcertificate.pem:p4ssphr4se -F parameter1=xxx -F parameter2=xxx -F parameter3=xxx -F xml=@test.xml https://test.xxx/action/batchUpload


    This code works like a charm.

    Now I have to convert this curl command to C# code. I'm using a HttpClient object with a handler with a certificate. I can't use a pem-file in my C# code so I'm using the p12 file.

    //try to create client certificate from settings
    var clientCertificatePath = appSettings[SETTING_KEY_CLIENT_CERTIFICATE_PATH];
    var clientCertificatePrivateKey = appSettings[SETTING_KEY_CLIENT_CERTIFICATE_PRIVATE_KEY];
    
    //create certificate from file 
    _clientCertificate = new X509Certificate2(System.Web.HttpContext.Current.Server.MapPath(clientCertificatePath), clientCertificatePrivateKey);
    
    WebRequestHandler handler = new WebRequestHandler();
    handler.ClientCertificates.Add(_clientCertificate);
    
    _httpClient = new HttpClient(handler);
    
    var testFilePath = System.Web.HttpContext.Current.Server.MapPath(@"~\test.xml");
    
    using (var form = new MultipartFormDataContent())
    {
    	form.Add(new StringContent("xxx"), "parameter1");
    	form.Add(new StringContent("xxx"), "parameter2");
    	form.Add(new StringContent("xxx"), "parameter3");
    
    	var fileData = File.ReadAllBytes(testFilePath);
    	var byteArrayContent = new ByteArrayContent(fileData, 0, fileData.Count());
    	byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
    
    	form.Add(byteArrayContent, "xml", "test.xml");
    
    	var response = _httpClient.PostAsync("https://test.xxx/action/batchUpload", form).Result;
    	using (HttpContent content = response.Content)
    	{
    		// ... Read the string.
    		Task<string> result = content.ReadAsStringAsync();
    		var res = result.Result;
    		System.Web.HttpContext.Current.Response.Write(res);
    	}
    }

    Now the problem I'm facing...

    If I run this code, my request seems to be authenticated ok, because if I don't use a certificate I receive a nice 403-response. But I add the certificate like in the code I'm receiving a 500-response.

    I compared the POST request I make with one I make with curl using Fiddler and the 100% the same the only difference is that in C# is use the p12-file and with curl I use the pem-file.

    So for me it seems the problem is with the file format of the client certificate I use. I read a lot about the different formats and for me it's quit confusing but I understood that p12 files ar used on Windows based systems and pem files are used on Unix/Linux based systems. And I'm thinking the problem might has something to do with this...

    Any help would be much appreciated!


    Friday, July 14, 2017 9:21 AM

All replies