Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net Windows 10的SChannel问题_.net_Networking_Sspi - Fatal编程技术网

.net Windows 10的SChannel问题

.net Windows 10的SChannel问题,.net,networking,sspi,.net,Networking,Sspi,我有一个应用程序,它使用System.Net.Security.SslStream类与服务器建立安全连接。在Windows7和Windows8/8.1上,这可以正常工作。在Windows 10上,对SslStream.AuthenticateAsClient的调用引发异常-“AuthenticationException:对SSPI的调用失败,请参阅内部异常”。内部异常为“Win32Exception:无法联系本地安全机构”。这不是特定于一台Windows 10计算机的 我认为这可能与服务器证书

我有一个应用程序,它使用System.Net.Security.SslStream类与服务器建立安全连接。在Windows7和Windows8/8.1上,这可以正常工作。在Windows 10上,对SslStream.AuthenticateAsClient的调用引发异常-“AuthenticationException:对SSPI的调用失败,请参阅内部异常”。内部异常为“Win32Exception:无法联系本地安全机构”。这不是特定于一台Windows 10计算机的

我认为这可能与服务器证书的公钥长度为512位有关,因此我使用512位公钥创建了自己的自签名证书,并在Windows 10计算机上测试了SslStream.authenticates客户端。这很有效

我正在试图找出是什么改变了Windows10,导致它不再工作。查看System.Net生成的日志和Wireshark的捕获,我看到客户端收到服务器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\u RSA\u和\u 3DES\u EDE\u CBC\u SHA是否存在问题?

好的,既然您在服务器中看到了密码套件Hello,我们可以得出结论,密码套件同时受客户端和服务器的支持,所以问题不在于密码套件

我怀疑问题出在您没有在密码套件中使用ECDHE或DHE时,您的512位证书。如果我没记错的话,Windows 10需要1024位(有效)或更多的密钥交换。由于您没有在密钥交换中使用ECDHE或DHE,它使用的是RSA,并且您的证书是512位,因此它尝试在密钥交换部分使用512位RSA。您的新服务器使用512位证书不会出现故障,因为它使用的是EC Diffie Hellman

您可以通过执行以下操作之一来测试这一点

  • 禁用新测试服务器上使用DHE或ECDHE的所有密码套件
  • 在“旧”服务器上启用DHE/ECDHE密码套件
  • 在“旧”服务器上使用1024位证书(不管怎样,我还是建议这样做,因为512位非常弱)

我们的.Net SSL客户端应用程序存在类似问题,该应用程序使用TLS1.0和TLS1.2连接到多个服务器

问题是Windows SChannel中的TLS1.2不支持某些弱密码套件,但是对于使用TLS1.0的连接,允许使用这些密码套件

随着.NET4.6.1的出现,Windows系统的行为发生了变化;在此版本之前,首选协议是TLS1.0,更新到版本>=4.6.1后,所有.Net客户端都会自动设置为TLS1.2。此外,某些KB安全更新可能会影响行为

第一种方法是修改应用程序以严格使用TLS1.0(从安全性角度来看这是不正确的):

第二种方法是使用免费工具IISCrypto,它可以帮助您禁用/启用协议和密码套件:


注意,这些设置存储在Windows注册表中,对于所有协议都是通用的,您可能需要“播放”配置,以找到最适合您使用的所有连接的设置。

要澄清,当您说“已使用”时,我想您的意思是您在服务器Hello中看到了它。如果您在ServerHello中看到了这一点,那么服务器同意使用该密码套件,因为它是在ClientHello中提供的,因此这不是密码套件问题。握手的具体失败之处是什么?正确,这就是我在ServerHello中看到的密码套件。握手似乎成功完成,但在收到ServerDone后,客户端立即关闭连接。InitializeSecurityContext函数返回错误代码0x80090304.OK,因此握手的工作方式是,客户端发送它支持的密码列表,服务器选择一个并在ServerHello中响应。因此,我们可以在这里看到,它不是专门的密码套件,因为客户机和服务器都同意TLS_RSA_和_3DES_EDE_CBC_SHA。我想我知道发生了什么。我会写一个答案。我没有访问“旧”服务器的权限。我刚刚创建了一个简单的TCP客户端应用程序和TCP服务器应用程序,它们使用SSL尝试复制问题。如果我禁用此测试系统上使用DHE或ECDHE的所有密码套件,服务器应用程序在收到ClientHello后会抛出一个异常——“客户端和服务器无法通信,因为它们没有通用算法”。这看起来很奇怪,因为客户机和服务器在同一台机器上。另外,您关于我的测试客户机/服务器工作的解释是有道理的,因为ECDHE用于密钥交换。我的理解正确吗?当Diffie Hellman用于密钥交换时,根本不使用证书公钥?
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls