我想将相互身份验证添加到在IIS服务器下运行的客户端.NET应用程序(它是一个调用其他Web服务的Web服务)。客户端应用程序从文件加载客户端证书,它在我的开发机器上使用以下代码正常工作(我尝试使用.NET 4.6.2的Windows 7和Windows 10):
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 Server计算机时,该应用程序将抛出The request was aborted: Could not create SSL/TLS secure channel.
我启用了对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_IUSRS
上的右键添加All Tasks -> Manage Private Keys...
时,一切正常,但我想避免这种情况。
有没有办法处理从Windows Server上的文件加载的客户端证书,而不是将客户端证书PFX文件导入证书存储区?
答案 0 :(得分:1)
首先,尝试X509KeyStorageFlags.PersistKeySet。接下来我理解你可以使用密钥将其导入密钥存储。如上所述here,您应首先将密钥导入到商店中(无论是否持久),然后使用密钥。
答案 1 :(得分:0)
由于工作涉及使用机器商店的示例,您可以尝试更改为MachineKeySet负载。
替换
var certificate = new X509Certificate2(clientCertPath);
与
var certificate = new X509Certificate2(clientCertPath, null, X509KeyStorageFlags.MachineKeySet);
此不应对于客户端身份验证证书,但如果您在加载和使用之间发生用户模拟,则可能导致用户密钥集问题。
答案 2 :(得分:0)
尝试一下,只需将其添加到启动代码中
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback =
(a, b, c, d) => true;