我想在IIS服务器下运行的client .NET应用程序(这是一个调用另一个Web服务的Web服务(。客户端应用程序从文件加载客户端证书,并且在我的开发计算机上使用以下代码(我尝试了Windows 7和Windows 10,使用.NET 4.6.2(:
(:var handler = new WebRequestHandler();
var certificate = new X509Certificate2(clientCertPath); -- PFX file with client cert and private key
handler.ClientCertificates.Add(certificate);
handler.AuthenticationLevel = AuthenticationLevel.MutualAuthRequired;
client = new HttpClient(handler);
但是,当将此代码部署到生产Windows 2016服务器计算机时,应用程序抛出The request was aborted: Could not create SSL/TLS secure channel.
i启用了System.Net
的跟踪,这就是我在日志中看到的
SecureChannel#66407304 - Certificate is of type X509Certificate2 and contains the private key.
AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent = Outbound, scc = System.Net.SecureCredential)
AcquireCredentialsHandle() failed with error 0X8009030D.
AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent = Outbound, scc = System.Net.SecureCredential)
AcquireCredentialsHandle() failed with error 0X8009030D.
Exception in HttpWebRequest#60537518:: - The request was aborted: Could not create SSL/TLS secure channel..
事实证明,由于IIS用户在PFX文件中读取私钥的权限,因此该错误是由于IIS用户的权限而引起的。因此,当我将其导入机器证书存储并通过单击客户端证书上的右键添加IIS_IUSRS
时,All Tasks -> Manage Private Keys...
一切正常,但是我想避免。
是否有一种方法可以使用Windows Server上从文件加载的客户端证书,并且不将客户端证书PFX文件导入证书存储?
首先,尝试x509Keystorageflags.persistKeySet。接下来,据我了解,您可以将其导入到密钥存储中的密钥。如下所述,您应该首先进入商店中的所有导入密钥(无论是否持久(,然后使用密钥。
由于事物工作的示例涉及使用机器商店,因此您可以尝试更改为MachineKeySet Load。
替换
var certificate = new X509Certificate2(clientCertPath);
var certificate = new X509Certificate2(clientCertPath, null, X509KeyStorageFlags.MachineKeySet);
客户身份验证证书不需要此,但是如果您在负载和使用之间发生用户模仿,则可能导致用户按键问题。
尝试一下,只需在启动代码
中添加它ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback =
(a, b, c, d) => true;