System.ServiceModel.ServiceActivationException when EnsureCertificateCanDoKeyExchange (netTcpBinding only)

This was a strange problem. I had a service with two endpoints, one with basicHttpBinding and one with netTcpBinding, both using transport security with certificates. If I tried to browse the service using IE I got a ServiceActivationException, and looking at the event log I was this:

“The certificate ‘SERIALNUMBER=…, CN=.., OU=Test, DC=Nod1, DC=Services, C=SE’ must have a private key that is capable of key exchange. The process must have access rights for the private key.”

I had checked that IIS APPPOOL\DefaultAppPool had access (full control) to the private key (using Certificate Manager, Manage Private Keys…) (This was Windows Server 2008 R2 with IIS 7.5 and .NET Framework 3.5.)

The strangest thing is that when I removed the netTcp endpoint, leaving only basicHttp, I didn’t get this error! From what I could see, they were both configured exactly the same.

It turned out to be a problem with the private key after all. Previously, when I imported the certificate (including private key) from a .p12 file using Windows Explorer, it ended up in Current User and I then moved it to Local Machine using the certificate console. That was obviously not the right way to do it. Instead, I had to open the certificate console, right click on Local Machine/Personal and choose All Tasks->Import… That imports the certificate to the right place. (You still must assign access to the private key to IIS APPPOOL\DefaultAppPool.)