在Windows服务中进行SSL连接时出现异常

问题描述:

我正在开发简单的Windows服务,从远程Web服务发送和接收数据。 我决定使用WebClient类为它的简单性和增强它包括在请求证书,像这样:在Windows服务中进行SSL连接时出现异常

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 Service中引发“无法为SSL/TLS建立安全通道”异常。 我试图在“localService”和“networkService”帐户下安装服务,并没有区别。

更新:在“用户”下安装也没有帮助。 我错过了什么吗?

+0

异常中是否有更多细节(例如'InnerException')?可以使用浏览器连接到端点吗?如果是的话,它显示的服务器证书是什么? – Richard 2012-01-10 08:47:58

+0

@Richard:内部异常为空。该服务基于一个完美运行的Windows桌面应用程序,这就是为什么我现在头脑发痒了两天...... – WojtekT 2012-01-10 08:55:42

+0

您是否尝试过将服务作为可以正常运行桌面应用程序的用户来安装? – CoreTech 2012-01-10 09:05:54

当加载这个证书:

X509Certificate cert = X509Certificate.CreateFromCertFile(appPath + @"\data\cert.der"); 

你只是加载证书。但是,要使客户端证书验证正常工作,您需要需要来提供私钥(否则任何人都可以使用任何证书)。

继在聊天室的讨论,你已经表明你也有一个.p12(PKCS#12),.key.pem文件,如意志为.der文件你试图加载。 通常,这些扩展以这种方式使用:

  • .der证书本身在DER编码(二进制)。
  • .pem用于PEM编码中的证书本身(DER的base64编码,---BEGIN....--- ... --- END ---分隔符内)。
  • .key为私钥。
  • .p12(或.pfx)用于PKCS#12文件,该文件将包含证书(可能还包括CA链)和私钥。

在.Net中,基地X509Certificate将不允许您加载私钥和证书。您应该考虑将p12文件加载到X509Certificate2实例中:它本质上是一个便利类,它不仅可以模拟证书,还可以将私钥与对象关联。

我不确定为什么这可以作为桌面应用程序而不是服务。我的猜测是,它会在某种情况下自动从用户或机器商店获取证书+私钥。无论哪种方式,您的桌面应用程序无论如何都不会简单地使用DER文件进行身份验证。

+1

用于从PKCS#12创建一个'X509Certificate2'实例(p12/pfx)文件,这应该有所帮助:http://msdn.microsoft.com/en-us/library/ms148420.aspx – Bruno 2012-01-10 13:17:12