【发布时间】:2016-02-19 20:03:09
【问题描述】:
我有一个使用 System.Net.Security.SslStream 类与服务器建立安全连接的应用程序。在 Windows 7 和 Windows 8/8.1 上,这可以正常工作。在 Windows 10 上,对 SslStream.AuthenticateAsClient 的调用会引发异常 - “AuthenticationException:对 SSPI 的调用失败,请参阅内部异常”。内部异常是“Win32Exception:无法联系本地安全机构”。这并不特定于一台 Windows 10 机器。
我认为这可能与服务器证书的公钥长度为 512 位有关,因此我使用 512 位公钥创建了自己的自签名证书,并使用它测试了 SslStream.AuthenticateAsClient Windows 10 机器。这工作得很好。
我正在尝试找出导致此功能不再起作用的 Windows 10 中的哪些变化。查看 System.Net 生成的日志和 Wireshark 的捕获,我看到客户端收到 SERVER HELLO、CERTIFICATE 和 SERVER DONE 消息,然后客户端关闭连接。在系统事件日志中,SChannel 记录了一个错误 - “已生成致命警报并将其发送到远程端点。这可能导致连接终止。TLS 协议定义的致命错误代码为 40。Windows SChannel 错误状态是 813。”显然 TLS 错误代码 40 是握手失败,但我无法找到有关 SChannel 错误状态 813 的任何信息。
通过查看 Wireshark 中的 SSL 握手,我发现正在使用 TLS_RSA_WITH_3DES_EDE_CBC_SHA 密码套件。当我连接到我创建的测试服务器(使用 512 位公钥证书)时,将使用 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 密码套件。在 Windows 10 上使用 TLS_RSA_WITH_3DES_EDE_CBC_SHA 是否存在问题?
【问题讨论】:
-
澄清一下,当您说“使用”时,我想您的意思是您在 ServerHello 中看到了它。如果您在 ServerHello 中看到了这一点,那么服务器同意使用该密码套件,因为它是在 ClientHello 中提供的,因此这不是密码套件问题。
-
握手失败的具体原因是什么?
-
正确,这是我在 ServerHello 中看到的密码套件。握手看似成功完成,但在收到 ServerDone 后,客户端立即关闭连接。 InitializeSecurityContext 函数返回错误代码 0x80090304。
-
好的,握手的工作方式,客户端发送它支持的密码列表,服务器选择一个并在 ServerHello 中响应。因此,我们可以在这里看到它并不是专门的密码套件,因为客户端和服务器都同意 TLS_RSA_WITH_3DES_EDE_CBC_SHA。我认为我知道发生了什么。我会写一个答案。
标签: .net networking sspi