WCF Web服务无法从证书中获取私钥

时间:2014-05-13 20:50:25

标签: c# web-services wcf ssl

我已经创建了一个托管在IIS中的WCF服务,我已经创建了一个CA makecert 和一个用于使用HTTPS来验证服务的证书。有了这个证书,我就可以了。现在我尝试在服务中使用Message Security。

web.config我有下一个代码:

<serviceCredentials>
        <serviceCertificate findValue="192.168.1.230" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
        <clientCertificate>
          <authentication certificateValidationMode="ChainTrust" />
        </clientCertificate>
      </serviceCredentials>

当我尝试通过Chrome等浏览器查看Web服务时,我收到了下一个错误System.Security.Cryptography.CryptographicException: KeySet does not exists。我查看了内部异常,这就是我所看到的

[CryptographicException: El conjunto de claves no existe]
   System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer) +5368074
   System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle) +138
   System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair() +221
   System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey() +516
   System.ServiceModel.Security.SecurityUtils.GetKeyContainerInfo(X509Certificate2 certificate) +45
   System.ServiceModel.Security.SecurityUtils.EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate) +76

[ArgumentException: Puede que el certificado 'CN=192.168.1.230' no tenga un clave privada capaz de intercambiar claves, o que el proceso no tenga permisos de acceso a la clave privada. Vea la excepción interna para obtener información detallada.]
   System.ServiceModel.Security.SecurityUtils.EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate) +16947147
   System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateLocalSecurityTokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement) +190
   System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement requirement) +50
   System.ServiceModel.Security.AsymmetricSecurityProtocolFactory.OnOpen(TimeSpan timeout) +930
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +740
   System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout) +79
   System.ServiceModel.Channels.SecurityChannelListener`1.OnOpen(TimeSpan timeout) +397
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +740
   System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +375
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +740
   System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +249
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +740
   System.ServiceModel.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity) +125
   System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) +901

[ServiceActivationException: El servicio '/WebFrontITAS.svc' no se puede activar debido a una excepción durante la compilación. El mensaje de la excepción es: Puede que el certificado 'CN=192.168.1.230' no tenga un clave privada capaz de intercambiar claves, o que el proceso no tenga permisos de acceso a la clave privada. Vea la excepción interna para obtener información detallada..]
   System.Runtime.AsyncResult.End(IAsyncResult result) +622882
   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +196075
   System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +282

我搜索了很多关于这一点,但我没有发现任何有用的东西。当我尝试使用FindPrivateKey.exe获取私钥时,它会失败并给我下一个错误No certificates with key '192.168.1.230' found in the store.

我不确定问题是出在证书上还是配置了WCF。

2 个答案:

答案 0 :(得分:5)

除了更改用户之外,解决此问题的另一种方法是给予应用程序池WCF服务在读取私钥的权限下运行。

打开系统的证书存储并找到您的证书,然后从中选择“管理私钥”

enter image description here

在安全设置中,通过添加名称IIS AppPool\App_Pool_Name_Here添加您的WCF服务正在运行的应用程序池(如果您在域中,请确保该位置设置为计算机而不是域)

enter image description here

然后选中Read权限框,您的应用应该可以开始阅读您的证书了。

enter image description here

注意:我遇到了一个错误,根据您导入证书的方式,程序仍然无法正常工作,我发现如果您使用IIS导入证书通常会发生这种情况。如果您使用内置于管理器的向导删除证书并从证书管理器内重新添加证书,它通常会解决问题。

答案 1 :(得分:2)

我已经解决了这个问题,问题是IIS的AppPool的身份验证,它使用的是没有访问证书存储区权限的网络凭据,当我将Autentification更改为LocalUser时,问题解决了。