我创建了一个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()不再返回,客户端因“错误连接重置”而被丢弃。
答案 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
标志。
这似乎完成了这项工作。该服务已经运行了近两天,仍然很乐意接受传入的连接。
希望这能让人免于我遇到的麻烦。