System.ComponentModel.Win32Exception: 客户端和服务器无法通信,因为它们没有共同的算法。

3

上个月我将客户的网站更新为默认安全模式。完全没有问题,但是本周(05/10 @大约上午10点),我开始收到异常信息,详细描述如下:

System.ComponentModel.Win32Exception: The client and server cannot communicate, because they do not possess a common algorithm

我连接AWS MySQL RDS数据库的字符串一直包括SSLMode=Required,花费了很长时间试图解决问题,最终将数据库的SSL模式设置为none。

唯一的结论是网站上的SSL证书与强制MySQL连接SSLMode Required之间存在冲突。

我已经将网站更新到.net 4.6.*,但仍然没有效果....

欢迎任何想法或建议....

我使用的工具有:MySQL Connector、AWS MySQL 5.6、.net 4.6

内部异常:

 System.Data.Entity.Core.ProviderIncompatibleException: An error occurred accessing the database. This usually means that the connection to the database failed. Check that the connection string is correct and that the appropriate DbContext constructor is being used to specify it or find it in the application's config file. See http://go.microsoft.com/fwlink/?LinkId=386386 for information on DbContext and connections. See the inner exception for details of the failure. ---> System.Data.Entity.Core.ProviderIncompatibleException: The provider did not return a ProviderManifestToken string. ---> System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> System.ComponentModel.Win32Exception: The client and server cannot communicate, because they do not possess a common algorithm
   --- End of inner exception stack trace ---
   at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
1个回答

3
请注意,我对MySQL Connector或AWS一无所知。尽管如此,我猜测如下:
从错误消息中,我们可以得出结论,客户端和服务器无法就密码套件达成一致。如果你还不了解这个主题,请注意以下内容:
SSL是一个协议,可以使用许多不同的密钥交换、加密和MAC算法。一个由(密钥交换、加密、MAC)算法(方法)组成的元组被称为一个“密码套件”。当建立SSL连接时,服务器和客户端需要协商使用哪种密码套件来交换密钥、加密和认证连接。
背后的原理是,新的、更安全的密码可以很容易地引入和使用,而不必改变SSL规范本身;旧的、不安全的、损坏的密码也可以很容易地删除,而不必改变SSL规范本身。
这意味着服务器的所有者可以说:“我向我的客户提供SSL,但只使用密码套件X、Y和Z”。如果客户端尝试连接,但仅支持密码套件A、B和C,则连接将失败。
现在,有时会因为某个密码套件被认为不安全而使其过时。在这种情况下,该密码套件通常会被安全更新默默禁用,这可能就是发生在您身上的情况:
当服务器已更新时,可能会禁用一个或多个SSL密码套件,这可能是通过MySQL的更新或操作系统本身或向应用程序提供加密服务的库的更新实现的。这可能导致您(客户端)和服务器不再具有共同的密码套件。
也有可能是相反的情况:如果您在客户端安装了更新或禁用了某些密码套件,则您的客户端和服务器可能无法再连接。
要确定如何调试此问题,我们需要更多地了解您的配置。然而,有一个一般的建议:
在SSL握手期间,客户端向服务器发送问候语,服务器也反过来。客户端和服务器在这个问候中展示他们支持的密码套件列表。由于客户端和服务器hello并没有被加密,因此你可以使用Wireshark等工具轻松地嗅探它们。然后,您可以比较客户端和服务器支持的密码套件列表,并检查是否至少存在一个共同的密码套件。
如果没有,您可能已经找到了问题。在这种情况下,您必须更改客户端或服务器端的配置,以便客户端和服务器再次具有至少一个共同的密码套件。如果您需要帮助执行此操作,请回来联系我,但请先按照上述建议分析情况。

1
好的答案。正如您所知,在TLS协商中,客户端首先发起通信。这与MySQL客户端/服务器协议不同,MySQL服务器会首先发起通信。因此,在使用TLS与MySQL时,通常会进行初始的MySQL握手,但是客户端在其“capabilities”数据包中设置了一个位标志,指示客户端将开始TLS协商,而不是提供身份验证数据。因此,在传输过程中,它与普通的TLS有所不同。这个细节排除了使用诸如openssl s_client之类的有用工具进行测试的可能性。我假设wireshark可以处理这个问题,但我不确定。 - Michael - sqlbot
这指引我朝着正确的方向前进。AWS 端的密码套件没有改变,所以我需要找到负责我的服务器的人解决问题的根本原因。这几乎肯定是答案,一旦我找到问题的根源,就会回来标记它。非常详细,非常感谢。 - Jon Selby
@Michael-sqlbot 感谢您的解释和+1。我不知道这一点,因为我总是使用典型的设置,在同一台机器上使用MySQL,并仅在本地侦听;因此,我从未使用过MySQL的SSL。不过,有一个要注意的地方:我强烈认为(即使考虑到MySQL奇怪的SSL实现),在某个时候会有一个未加密的客户端和服务器hello。因此,您可以捕获数据包,即使没有正确解析它们,这些hello也将出现在原始数据中。由于这发生在连接开始时,因此应该很容易找到它们。 - Binarus
@JonSelby 谢谢。我思考了很长时间是否应该回答,因为我对AWS和MySQL连接器一无所知,不想让自己出丑。此外,错误消息的措辞完全不同寻常。任何熟悉SSL等内容的人都不会说“拥有共同算法”(通常的措辞可能是“不支持密码套件”或类似的)。我不知道微软开发人员在实现该错误消息之前吸了什么东西,但这几乎让我不敢回答,因为我认为它与通常的密码套件问题无关。 - Binarus
@Binarus 评论说,如果微软能够用常识性的错误信息来提示程序错误,那么当出现问题时,他们的框架将变得更加容易处理。感谢stackoverflow的存在... - Jon Selby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接