【发布时间】:2019-09-30 14:34:13
【问题描述】:
我正在使用 WebRequest 连接到使用 https 的网页。
如果我尝试使用 LocalMachine 的个人存储中的客户端证书
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:\temp\file.p12";
var clientCertificate = new X509Certificate2(certificatePath, "pwd",
X509KeyStorageFlags.Exportable);
和
req.ClientCertificates.Add(clientCertificate);
我将能够成功运行 https 查询。
这要求我在文件系统中保存一个文件,并在源代码中输入密码。
如何使用存储而不是文件系统?
为什么我必须使用
validOnly: false来获取客户端证书?
编辑
访问这些证书(客户端和服务器证书)的首选方法是将它们作为端点放在 web.config 中,但我没有成功。
【问题讨论】:
-
运行此应用程序的用户是否有权访问证书的私钥?
-
是的,用户属于管理员组。它是一个桌面应用程序。
-
您是如何将证书导入商店的?是否有可能遗漏了私钥?
-
如果我右键单击“管理计算机证书”中的证书,所有任务 -> 管理私钥将向我显示私钥的权限。这是否表明那里有私钥?
-
在来自
Find的clientCertificates集合中,它是非空集合吗?是否有任何证书报告true为HasPrivateKey?
标签: c# ssl x509certificate client-certificates