WCF 服务配置异常“证书可能没有私钥......”

Posted

技术标签:

【中文标题】WCF 服务配置异常“证书可能没有私钥......”【英文标题】:WCF service config exception "it is likely that certificate may not have a private key..." 【发布时间】:2013-07-01 03:42:36 【问题描述】:

在我上一个问题 - WCF client for consuming ASMX service with WS-Security 之后,我需要配置一个 WCF 服务,该服务将使用 WS-Security 接收 SOAP 请求(可以在链接中找到请求示例)。

这是我的配置文件:

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

服务证书包含私钥以对响应进行签名。 客户端证书仅包含用于签署请求的客户端私钥的对应公钥。

我收到以下与服务证书相关的异常: "证书 'CN=xxxxxx' 必须具有能够进行密钥交换的私钥。进程必须具有私钥的访问权限。"

我该如何解决?

提前致谢!

编辑:

我得到的异常:

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)

【问题讨论】:

【参考方案1】:

如果错误是在服务器或客户端证书上,则无法从消息中清除。无论如何,您只需要配置服务器证书。客户端证书将根据您可以在行为中指定的策略进行验证。

你可以使用这个绑定:

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

还要确保使用以下内容装饰服务合同:

[ServiceContract(ProtectionLevel=System.Net.ProtectionLevel.Sign)]

【讨论】:

检查您是否拥有一个私钥并且您有权访问它。更多信息在这里webservices20.blogspot.co.il/2011/02/… 尝试暂时使用不同的密钥,可能是 wcf 示例提供的并且已知可以工作的密钥,以查看是否存在相同的错误 更新了我的答案,现在看看里面的配置+属性定义 尝试另一个证书。可能你的进程没有权限。 我使用 make cert.exe 创建了一个证书,在 -sky 之后使用 'exchange' 值(而不是我之前使用的 'signature' 值),现在一切正常!这是什么原因?【参考方案2】:

在 Windows 8.1 上使用 Visual Studio 2012 调试客户端应用程序时,我遇到了同样的问题。根据给出的错误消息,您在从 Visual Studio 运行应用程序时也会收到此错误。打开Visual Studio“以管理员身份运行”即可解决问题。

【讨论】:

以上是关于WCF 服务配置异常“证书可能没有私钥......”的主要内容,如果未能解决你的问题,请参考以下文章

WCF:在嵌套服务调用中保留内部异常

Wcf 服务异常良好实践

ASP.NET 中的 WCF 模拟异常

WCF 协议异常

从第三方 WCF 获取底层异常 - SOAP 异常

WCF 服务中的异常