C# 从文件加载客户端证书的HttpClient

C# 从文件加载客户端证书的HttpClient,c#,iis,dotnet-httpclient,client-certificates,mutual-authentication,C#,Iis,Dotnet Httpclient,Client Certificates,Mutual Authentication,我想向在IIS服务器下运行的客户端.NET应用程序(它是一个调用另一个web服务的web服务)添加相互身份验证。客户端应用程序从文件中加载客户端证书,它在我的开发计算机上与以下代码配合良好(我使用.NET 4.6.2试用了Windows 7和Windows 10): 但当此代码部署到生产Windows 2016 Server计算机时,应用程序抛出请求被中止:无法创建SSL/TLS安全通道。 我为System.Net启用了跟踪,这是我在日志中看到的 SecureChannel#66407304 -

我想向在IIS服务器下运行的客户端.NET应用程序(它是一个调用另一个web服务的web服务)添加相互身份验证。客户端应用程序从文件中加载客户端证书,它在我的开发计算机上与以下代码配合良好(我使用.NET 4.6.2试用了Windows 7和Windows 10):

但当此代码部署到生产Windows 2016 Server计算机时,应用程序抛出
请求被中止:无法创建SSL/TLS安全通道。

我为
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时,
所有任务->管理私钥…
一切正常,但我希望避免这种情况


是否有一种方法可以处理从Windows Server上的文件加载的客户端证书,而不将客户端证书PFX文件导入证书存储

首先,尝试x509keystrageflags.PersistKeySet。接下来,据我所知,您可以使用密钥将其导入密钥存储。如前所述,您应该首先将密钥导入存储(无论是否持久),然后使用该密钥。

由于工作示例涉及使用机器存储,您可以尝试更改为MachineKeySet加载

替换

var certificate = new X509Certificate2(clientCertPath);


对于客户端身份验证证书,这应该不是必需的,但是如果在加载和使用之间发生用户模拟,可能会导致用户密钥集问题。

尝试此操作,只需将其添加到启动代码中即可

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

        ServicePointManager.ServerCertificateValidationCallback =
            (a, b, c, d) => true;

您的客户机在哪里运行?客户机是什么类型的应用程序?客户端是否在IIS工作进程内运行?它把错误抛到哪里去了?客户端还是服务器端?使用客户端相互身份验证对远程服务器进行HTTP调用的.NET web应用程序。它正在IIS工作进程内运行。错误在客户端当您导入到用户证书存储时它是否工作,或者您是否正在使用机器证书存储?我将它导入到机器存储,因为它应该由不同的用户访问,是,当我导入它并将其添加到
IIS\u IUSRS
所有任务->管理私钥…
我将编辑问题…我尝试了,但不幸的是它没有工作。我确实希望避免将密钥导入存储并使用pfx文件,因为它在桌面Windows上工作。IIS应用程序池标识如何?您是否尝试将默认ApplicationPoolIdentity更改为具有更高权限的用户?
var certificate = new X509Certificate2(clientCertPath, null, X509KeyStorageFlags.MachineKeySet);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

        ServicePointManager.ServerCertificateValidationCallback =
            (a, b, c, d) => true;