1

I have written an application (in C#) to communicate with one of our customers via a web service. Our customer requires us to use bi-directional SSL. The customer has sent us their certificate (in the form of a .p7b file). The client certificate was provided to me in the form of a .cer file.

I've installed the certificates and in the program I use the HttpWebRequest class and add the client certificate to the ClientCertificates collection.

When I run the program I get an exception:

System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.

I have used WireShark to try to diagnose the error and I see this (IP Addresses redacted):

1615    12.259771000    CLIENT_IP   SERVER_IP   SSLv3   112 Client Hello
1629    12.429299000    SERVER_IP   CLIENT_IP   SSLv3   1488    Server Hello, Certificate, Certificate Request, Server Hello Done
1630    12.445672000    CLIENT_IP   SERVER_IP   SSLv3   397 Alert (Level: Warning, Description: No Certificate), Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
1645    12.666191000    SERVER_IP   CLIENT_IP   SSLv3   61  Alert (Level: Fatal, Description: Handshake Failure)

It seems the server has sent their certificate, but for some reason, my app is not sending one back, so it sends the No Certificate alert. However, in my code, it seems to find the certificate and it is added to the ClientCertificate collection of the HttpWebRequest class. Since I fairly new to SSL, I am not sure where the problem lies? It could be a programming mistake, but using some test certficates seemed to work. Does the alert indicate that there is a problem with the client certificate? Some posts that I have read seem to indicate that although the private key is not sent to the server, it is still needed on the client side. But after loading the certificate (using the .Net X509Certificate2 class), I notice that the PrivateKey property is null. Could this be the source of the problem? The .cer file was provided to me by someone else in the company.

Any assistance or suggestions would be helpful. I have refrained from posting code as I'm not sure it's welcome here, but I can post some if need be.

2

Well no, that won't work for you. The point of a client cert isn't really the cert part, but the private key tied to the client cert. If you don't have the private key you can't do anything useful. What would happen is that the request you send is encrypted with the servers public key and decrypted with their private key. Conversely, any response the server sends is encrypted with your public key (the cert). To decrypt the response you need a private key.

What you need from the other people is the PFX file. In actual fact, you should generate the keys locally, and send THEM the client cert. Just the cert though, not the private key.

  • The .cer file came from a CA (Go Daddy). So the customer needs the .cer file (public key) but my app will need the private key to decrypt data that was encryped with my public key. I presume that in my app, I will load the public and private keys but during the handshake, it will only transmit the public key, correct? – Chris Dunaway Feb 18 '14 at 17:08
  • Correct. Given your code, you'd load up an X509Certificate2 and that would have a PrivateKey property that is not null. – Steve Feb 18 '14 at 17:15
  • Is any part of the handshake encrypted? – Chris Dunaway Feb 18 '14 at 20:48
  • Sure, but that becomes a bit more complicated of a discussion. What are you trying to figure out specifically? – Steve Feb 18 '14 at 21:38
  • I guess I was just wondering if the server encrypts their certificate with the client's public key. And if so, then if the private key is missing, then client cannot verify the server's certificate. – Chris Dunaway Feb 18 '14 at 21:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.