C# 为什么我会得到;无法创建SSL/TLS安全通道“;何时附加客户端证书?

C# 为什么我会得到;无法创建SSL/TLS安全通道“;何时附加客户端证书?,c#,security,ssl,ssl-certificate,C#,Security,Ssl,Ssl Certificate,当我的代码试图向服务器发送请求时,我看到了这条消息,该服务器要求请求附带一个带有私钥的客户端证书(这可能是一个错误)。使用通过SoapUI发送的请求,我已经验证了证书是否有效。我的代码是否以错误的方式附加证书 代码如下所示(它可能包含许多在搜索难以捉摸的解决方案时不需要的内容): 本例中的问题在于证书,特别是私钥 我使用的是.cer证书,其行为与.pfx文件不同。SoapUI和curl在.cer上都可以正常工作,但是加载.cer的C#code会丢失私钥。(为什么我们连接到的服务器需要私钥是另一个

当我的代码试图向服务器发送请求时,我看到了这条消息,该服务器要求请求附带一个带有私钥的客户端证书(这可能是一个错误)。使用通过SoapUI发送的请求,我已经验证了证书是否有效。我的代码是否以错误的方式附加证书

代码如下所示(它可能包含许多在搜索难以捉摸的解决方案时不需要的内容):


本例中的问题在于证书,特别是私钥

我使用的是
.cer
证书,其行为与
.pfx
文件不同。SoapUI和curl在
.cer
上都可以正常工作,但是加载
.cer
的C#code会丢失私钥。(为什么我们连接到的服务器需要私钥是另一个问题-我的理解是不应该-感谢您对此有任何想法。)同样,通过MMC管理单元加载到存储的
.cer
文件也会丢失私钥。我还不知道为什么

虽然我最初将
.pfx
文件加载到证书存储中的努力是成功的,但当我开始在其他帐户下运行我的应用程序时,返回了“无法创建SSL/TLS安全通道”错误(解释和)。本质上,证书存储将私钥保存在文件系统位置,只有将证书加载到存储中的用户才能访问该位置

相反,我直接从文件系统加载证书,如下所示:

var certBytes = File.ReadAllBytes(certFileName);
var certificate = new X509Certificate2(certBytes, password, X509KeyStorageFlags.Exportable);

var httpClientHandler = new HttpClientHandler();
httpClientHandler.ClientCertificates.Add(certificate);
var request = new HttpRequestMessage(HttpMethod.Post, url)
{
    Content = new StringContent(requestBody, Encoding.UTF8, "application/xml")
};

var httpClient = new HttpClient(httpClientHandler);

httpClient                   
    .DefaultRequestHeaders
    .Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

// fire!
var response = await httpClient.SendAsync(request).ConfigureAwait(false);

我怀疑这一行可能是原因
var certificate=new X509Certificate(certName,password,X509KeyStorageFlags.UserKeySet)我会尝试X509Certificate2。首先打开X509Store(CurrentUser\My),找到要使用的客户端SSL证书并将其添加到
httpClientHandler.ClientCertificates
@pepo,在存储中查找证书时遇到一些问题。存储在某种程度上是该过程的必要部分,还是我可以简单地使用
X509Certificate2
代替
X509Certificate2
,同时仍然从文件系统导入?如果您有pfx/pkcs12文件,那么您不必使用x509store。只需创建新的x509certificate2实例。@pepo,我实际上有一个.cer文件,这就是问题所在。谢谢你的意见。
var certBytes = File.ReadAllBytes(certFileName);
var certificate = new X509Certificate2(certBytes, password, X509KeyStorageFlags.Exportable);

var httpClientHandler = new HttpClientHandler();
httpClientHandler.ClientCertificates.Add(certificate);
var request = new HttpRequestMessage(HttpMethod.Post, url)
{
    Content = new StringContent(requestBody, Encoding.UTF8, "application/xml")
};

var httpClient = new HttpClient(httpClientHandler);

httpClient                   
    .DefaultRequestHeaders
    .Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

// fire!
var response = await httpClient.SendAsync(request).ConfigureAwait(false);