1

After my previous question - WCF client for consuming ASMX service with WS-Security , I need to configure a WCF service that will receive SOAP requests using WS-Security (request sample can be found in the link).

This is my config file:

  <system.serviceModel>
    <services>
      <service name="Service.Service1" behaviorConfiguration="customBindingBehavior">
        <endpoint address="http://localhost/Service1.svc" 
                  binding="customBinding"
                  bindingConfiguration="NewBinding0" 
                  name="ServiceEndpoint"
                  contract="Service.Contracts.IService1" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="customBindingBehavior">
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceMetadata httpGetEnabled="true" />
          <serviceCredentials>
            <serviceCertificate findValue="xxx" x509FindType="FindByThumbprint" storeLocation="LocalMachine" storeName="My" />
            <clientCertificate>
              <certificate findValue="yyy" x509FindType="FindByThumbprint" storeLocation="LocalMachine" storeName="TrustedPeople" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <customBinding>
        <binding name="NewBinding0">
          <textMessageEncoding messageVersion="Soap11WSAddressingAugust2004" />
          <security authenticationMode="MutualCertificate">
            <secureConversationBootstrap />
          </security>
          <httpTransport />
        </binding>
      </customBinding>
    </bindings>
  </system.serviceModel>
</configuration>


The service certificate contains private key in order to sign the response.
The client certificate contains only the corresponding public key of the client's private key that was used to sign the request.

I get the following exception associated with the service certificate:
"The certificate 'CN=xxxxxx' must have a private key that is capable of key exchange. The process must have access rights for the private key."

How can I fix it?

Thanks in advance!

EDIT:

The exception I get:

System.ArgumentException: It is likely that certificate 'CN=xxx' may not have a private key that is capable of key exchange or the process may not have access rights for the private key.
at System.ServiceModel.Security.SecurityUtils.EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate)
at System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateServerX509TokenProvider()
at System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateLocalSecurityTokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement)
at System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement requirement)
at System.ServiceModel.Security.AsymmetricSecurityProtocolFactory.OnOpen(TimeSpan timeout)
at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Security.SecurityProtocolFactory.Open(Boolean actAsInitiator, TimeSpan timeout)
at System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelListener`1.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open()
at Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)
Community
  • 1
  • 1
Sash
  • 493
  • 2
  • 10
  • 19

2 Answers2

2

Not clear from the message if the error is on the server or client cert. Anyway you only need to configure the server cert. The client cert wil be validated according to a policy you can specify in the behavior.

you can use this binding:

<customBinding>
                <binding name="NewBinding0">
                    <textMessageEncoding messageVersion="Soap11" />
                    <security authenticationMode="MutualCertificate" messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
                        <secureConversationBootstrap />
                    </security>
                    <httpTransport />
                </binding>
</customBinding>

also make sure to decorate the service contract with:

[ServiceContract(ProtectionLevel=System.Net.ProtectionLevel.Sign)]
Yaron Naveh
  • 23,560
  • 32
  • 103
  • 158
  • You mean I need to use element of ? – Sash Jul 04 '13 at 07:32
  • I followed your comment and still I get the same exception. I've updated the question with the stack trace of the exception. It seems that the error is caused by the server cert. – Sash Jul 07 '13 at 06:26
  • 1
    check that you have a pricate key and you have permissions to it. more information here http://webservices20.blogspot.co.il/2011/02/wcf-keyset-does-not-exist.html – Yaron Naveh Jul 07 '13 at 09:48
  • I have both private key and permissions, but still the same exception exists. Any suggestions? – Sash Jul 07 '13 at 11:24
  • 1
    try to use a different key temporarly, maybe one which is provided with wcf samples and known to work, to see if same error exist – Yaron Naveh Jul 07 '13 at 13:45
  • I used a working key and still the same problem exists. Can you provide a WCF service config that receives signed SOAP requests and then signs the response? – Sash Jul 08 '13 at 12:14
  • 1
    updated my answer, see the config + attribute defintion in it now – Yaron Naveh Jul 10 '13 at 11:10
  • Thanks, but still I have the same issue. Maybe the problem is the behavior section of the config (although I followed your original answer) ? – Sash Jul 10 '13 at 11:19
  • 1
    try another certificate. maybe your process does not have permissions. – Yaron Naveh Jul 10 '13 at 11:54
  • 1
    I've created a certificate using make cert.exe with 'exchange' value after -sky (instead of 'signature' value that I was using before) and now everything works great! What is the reason for this ? – Sash Jul 17 '13 at 13:36
  • 1
    you can read about the different types here http://msdn.microsoft.com/en-us/library/bfsktky3.aspx, in general for web services you need the "exchange" that allows encryption and key exchange – Yaron Naveh Jul 17 '13 at 15:06
0

I had the same problem when debugging the client application using Visual Studio 2012 on Windows 8.1. Based on the error message given you are also getting this error while running the application from Visual Studio. Opening Visual Studio “Run as administrator” solve the problem.

Dush
  • 1,185
  • 26
  • 29