从Windows服务中进行SSL连接时发生异常
本文关键字:连接 异常 SSL Windows 服务 | 更新日期: 2023-09-27 18:19:56
我正在开发从远程web服务发送和接收数据的简单Windows服务。为了简单起见,我决定使用WebClient类,并将其增强为在请求中包含证书,如下所示:
class MyWebClient : WebClient
{
public X509Certificate cert { set; get; }
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest req = (HttpWebRequest)base.GetWebRequest(address);
req.ClientCertificates.Clear();
req.ClientCertificates.Add(cert);
return req;
}
}
这就是我准备和提出请求的方式:
try {
//...
string qry = "Some xml query...";
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors) { return true; };
X509Certificate cert = X509Certificate.CreateFromCertFile(appPath + @"'data'cert.der");
MyWebClient cl = new MyWebClient();
cl.cert = cert;
string xmlReq = qry;
cl.Headers[HttpRequestHeader.ContentType] = "text/xml";
var data = Encoding.UTF8.GetBytes(xmlReq);
byte[] res = cl.UploadData(apiUrl, data);
cl.Dispose();
string result = Encoding.UTF8.GetString(res);
} catch (Exception ex) {
//...
}
//...
现在,我知道从文件加载证书不是最好的主意,但这不是重点。重点是,上面的代码在桌面应用程序中运行良好,但在Windows服务中引发了"无法为SSL/TLS建立安全通道"异常。我尝试在"localService"answers"networkService"帐户下安装该服务,这没有任何困难。
更新:在"user"下安装也没有帮助。我是不是错过了什么?
当您加载带有以下内容的证书时:
X509Certificate cert = X509Certificate.CreateFromCertFile(appPath + @"'data'cert.der");
你只是在加载证书。但是,要使客户端证书身份验证工作,还需要提供私钥(否则,任何人都可以使用任何证书)。
在聊天室中进行讨论后,您表示您还有一个.p12
(PKCS#12)、一个.key
和.pem
文件,以及您试图加载的.der
文件。通常,这些扩展是这样使用的:
- 用于DER编码(二进制)中的证书本身的
.der
- 证书本身在PEM编码中的
.pem
(DER的base64编码,在---BEGIN....--- ... --- END ---
分隔符内) .key
作为私钥- PKCS#12文件的
.p12
(或.pfx
),该文件将包含证书(可能还有CA链)和私钥
在.Net中,基本X509Certificate
不允许您将私钥与证书一起加载。您应该考虑将p12文件加载到X509Certificate2
实例中:它本质上是一个方便类,不仅可以为证书建模,还可以将私钥与对象关联。
我不知道为什么这是一个桌面应用程序而不是一个服务。我的猜测是,在其中一种情况下,它会自动从用户或机器存储中获取cert+私钥。不管怎样,您的桌面应用程序都不是简单地使用DER文件进行身份验证。