1

After searching a lot and trying other's answers, every solution - still without success

Short preface : response request from my machine to itself - does work with certificate. From another computer to my machine - it doesn't.

In my machine- I've created 2 certificates : public key and private key via :

makecert -r -pe -n "CN=ds.com" -b 01/01/2018 -e 01/01/2020 
-sky exchange Server.cer -sv Server.pvk

And then :

pvk2pfx.exe -pvk Server.pvk -spc Server.cer -pfx Server.pfx

(taken from here)

I've installed them both in the store in my machine(via mmc) :

enter image description here

I'm using this simple WCF config which I host in WAS IIS at my machine.

When I call that service (from my machine to itself) with this simple code:

  WSHttpBinding myBinding = new WSHttpBinding();
            myBinding.Security.Mode = SecurityMode.Message;
            myBinding.Security.Message.ClientCredentialType =MessageCredentialType.Certificate;
            EndpointAddress ea = new
                EndpointAddress("http://ds.com/Service1.svc/HelloWorldService");

            var client   = new HelloWorldServiceClient(myBinding, ea);

            client.ClientCredentials.ClientCertificate.SetCertificate(
                StoreLocation.CurrentUser,
                StoreName.Root,
                X509FindType.FindByThumbprint,
                "9394f570069e7af263ef7ca5a46a5bcab9f68659");
    Console.WriteLine(client.GetMessage("Mike Liu"));
    Console.ReadLine();
    client.Close();

— I DO get result :

enter image description here

Great.

Now let's go to another computer which I've installed in only the public key certificate into the trusted root.

However - now when I access my computer (with the same code ^) - I get the following error:

The certificate 'CN=ds.com' must have a private key. The process must have access rights for the private key.

Even if I shutdown the WAS IIS service at my computer , I still see the error at the other machine.

It seems that the problem is only at the other machine. I've already set permission in the other machine:

C:\ProgramData\Microsoft\Crypto <--------Everyone: full control +inheritance

Question:

What am I missing here ? Why does it look for a private key in the client machine. It is not supposed to have the private key. The private should only reside in the service computer. (which is my machine).

Full stack trace image (at the other machine)

Royi Namir
  • 144,742
  • 138
  • 468
  • 792

2 Answers2

1

In your example you are using the same certificate on server and client. That is not what it should be.

In order to secure client request, you have to sign request with client certificate and server response is signed with server certificate.

So on client you should have:

  • private (and public) key of client certificate in it's personal certificate store
  • public key of server certificate within trusted root authorities

On server you should have the oposite:

  • private (and public) key of server certificate in it's personal certificate store
  • public key of client certificate within trusted root authorities

You can see example here and read more about it here.

Details about the HTTPS protocol are very nicely described in this article.

danijelk
  • 6,749
  • 2
  • 16
  • 11
  • Thanks for replying - To my understanding ( possibly wrong) , the server should have public and private certificaes. While users should only have public. and they can encrypt data , which only the Private key can open. No ? If so - I don't understand why clients around the world should have private key. – Royi Namir Jul 04 '18 at 14:05
  • In communication between client and server you have both request and response. Request from client is encrypted with server public key and decrypted with server private key on server. Response from server is encrypted with client public key and decrypted on client with client private key. So yes you need both. – danijelk Jul 04 '18 at 14:07
  • Hi. You said "_Details about the HTTPS_" - but my code uses `EndpointAddress ea = new EndpointAddress("http://ds.com/Service1.svc/HelloWorldService");` ( not HTTPS). So how come it works ? Also - Does the ` client.ClientCredentials.ClientCertificate.SetCertificate` code is for the encryption of the message or for decryption - when response is back from server ? – Royi Namir Jul 05 '18 at 06:52
  • I wasn't really paying attention on that. You are using `SecurityMode.Message`. That means message is encrypted and not the transport layer (HTTPS). Still theory on public/private keys and encritption is the same. You can see differences of WCF security modes in [this question](https://stackoverflow.com/questions/5673283/wcf-transport-vs-message). – danijelk Jul 09 '18 at 23:03
0

This might be due to 2 possible reasons.

  1. no private key avaialble in certificate current user store (personal/trusted people)
  2. IIS application pool do not have access of private key for (current user store)

enable wcf trace and you will find error in log mentioned in image.

enter image description here

for 1) install private key (pfx) for 2nd provide identity in application pool as given in below image. enter image description here