不能使用证书存储中的客户端证书,只能从文件加载



我正在使用WebRequest连接到使用https的网页。

如果我尝试使用本地计算机中个人存储中的客户端证书,请使用

var myStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
myStore.Open(OpenFlags.ReadOnly);
var clientCertificates = myStore.Certificates.Find(X509FindType.FindBySubjectName, "foobar",
validOnly: false);

然后我创建了一个连接

var req = (HttpWebRequest)WebRequest.Create("https://theserver.com/the/url");
req.Method = "POST";
req.ContentType = "application/json";
req.ProtocolVersion = HttpVersion.Version11;
req.ClientCertificates = clientCertificates; 
req.ServerCertificateValidationCallback += (o, certificate, chain, errors) =>
{
return true;
};
using (var stream = req.GetRequestStream())
{
stream.Write(data, 0, data.Length);
stream.Flush();
}
var response = req.GetResponse();

我在req.GetResponse线上失败了

System.Net.WebException:"请求已中止:无法创建 SSL/TLS 安全通道。

但是,如果我改为从文件加载客户端证书(我之前在存储中安装的相同文件(

var certificatePath = @"C:tempfile.p12";
var clientCertificate = new X509Certificate2(certificatePath, "pwd", 
X509KeyStorageFlags.Exportable);

req.ClientCertificates.Add(clientCertificate);

我将能够成功运行https查询。

这既要求我在文件系统中保留一个文件,也需要在源代码中输入密码。

  • 如何使用存储而不是文件系统?

  • 为什么必须使用validOnly: false来获取客户端证书?

编辑

访问这些证书(客户端和服务器证书(的可行方法是将它们作为端点在 web.config 中,但我还没有成功做到这一点。

为了解决问题/许多问题的症状,我不得不将用户 Everyone 添加到证书私钥的 ACL 中。

我没有更改私钥的 ACL,而是发现如果我只给它公钥,ClientCertificates 属性就会很好地工作。 是的,如果您在存储中没有私钥,身份验证将不起作用,但转换为仅公钥证书似乎每次都对我有用。

var publicKeyOnly = new X509Certificate2(authenticationCert.Export((X509ContentType.Cert));

最新更新