带有SSL证书的HttpListener挂在GetContext()上

时间:2015-05-08 19:36:19

标签: c# .net windows ssl httplistener

我创建了一个Windows服务,它使用HttpListener响应使用.NET Framework 4.0的某些第三方请求。侦听器通过以下方式绑定到https前缀:

d.env = {
        "SSH_PORT":"23"
}

该服务还通过以下方式在计算机商店中自行注册https证书:

listener.Prefixes.Add("https://+:" + Properties.Settings.Default.ListeningPort.ToString() + "/");

此外,该服务还使用以下内容在Http API中注册证书-ip:port binding:

X509Certificate2 certificate = new X509Certificate2(Properties.Settings.Default.HttpsCertPath, "", X509KeyStorageFlags.MachineKeySet);
X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);
store.Close();

一切运作良好,正如所料......除了......(这里是EVIL部分): 运行一段时间后,一小时左右,listener.GetContext()不再返回,客户端因“错误连接重置”而​​被丢弃。

1 个答案:

答案 0 :(得分:4)

经过长时间的痛苦调查后,我发现错误发生在HTTP API级别,并且在SSL握手期间会发生故障,因此listener.GetContext()根本不会返回。更进一步,我发现每次失败的请求,在Windows事件日志的系统日志中,都会记录以下错误:

Source Schannel: A fatal error occurred when attempting to access the SSL server credential private key. The error code returned from the cryptographic module is 0x8009030D. The internal error state is 10001.

Source HttpEvent: An error occurred while using SSL configuration for endpoint 0.0.0.0:9799.  The error status code is contained within the returned data.

进一步深入研究这个问题我注意到,一旦私钥从安装的证书中消失了。结合我在this link阅读的内容,这让我有所不同。所以我试了一下:

X509Certificate2 certificate = new X509Certificate2(Properties.Settings.Default.HttpsCertPath, "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);

基本上,我已经放入了X509KeyStorageFlags.Exportable(还记得创建SSL绑定时遇到的错误,如果你没有将证书标记为可以在IIS上导出吗?)和X509KeyStorageFlags.PersistKeySet标志。 这似乎完成了这项工作。该服务已经运行了近两天,仍然很乐意接受传入的连接。

希望这能让人免于我遇到的麻烦。