我已经创建了一个托管在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。
答案 0 :(得分:5)
除了更改用户之外,解决此问题的另一种方法是给予应用程序池WCF服务在读取私钥的权限下运行。
打开系统的证书存储并找到您的证书,然后从中选择“管理私钥”
在安全设置中,通过添加名称IIS AppPool\App_Pool_Name_Here
添加您的WCF服务正在运行的应用程序池(如果您在域中,请确保该位置设置为计算机而不是域)
然后选中Read
权限框,您的应用应该可以开始阅读您的证书了。
注意:我遇到了一个错误,根据您导入证书的方式,程序仍然无法正常工作,我发现如果您使用IIS导入证书通常会发生这种情况。如果您使用内置于管理器的向导删除证书并从证书管理器内重新添加证书,它通常会解决问题。
答案 1 :(得分:2)
我已经解决了这个问题,问题是IIS的AppPool的身份验证,它使用的是没有访问证书存储区权限的网络凭据,当我将Autentification更改为LocalUser时,问题解决了。