从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"下安装也没有帮助。我是不是错过了什么?

从Windows服务中进行SSL连接时发生异常

当您加载带有以下内容的证书时:

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文件进行身份验证。