Search code examples
c#wcfiiscertificatemakecert

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


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)


Solution

  • 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.