【发布时间】:2018-08-22 23:01:05
【问题描述】:
我用 C# 编写了一个 REST API 服务器,它使用 System.Net.Security.SslStream 类来提供 SSL/TLS 加密。
我还在创建一个使用 PHP + cURL 来处理与服务器通信的 Web 服务。
在本地,我使用 WAMP 作为测试环境,一切正常。
但是,在远程环境上上传和测试时,通信失败并显示以下错误消息:
cURL 错误
Unknown SSL protocol error in connection to mywebsite.example:443
SslStream 错误
AuthenticationException in SslStream.AuthenticateAsServer():
A call to SSPI failed, see inner exception.
Inner exception: The client and server cannot communicate, because they do not possess a common algorithm
尝试使用 TLS 1.2 身份验证时出现此异常和错误:
SslStream.AuthenticateAsServer(ServerCertificate, false, SslProtocols.Tls12, true);
我尝试设置各种 cURL 选项,例如:
curl_setopt($curl, CURLOPT_SSLVERSION,CURL_SSLVERSION_TLSv1_2);
但是,唉,没有快乐。
检查phpInfo() 配置的差异后,我注意到在本地的 cURL 设置中启用了 SSPI,但在远程服务器上没有启用:
我对 SSPI 知之甚少,事实上,大多只是维基百科上的总结:
安全支持提供程序接口 (SSPI) 是一个 Win32 API,由 Microsoft Windows 系统执行各种与安全相关的 身份验证等操作。
所以,这似乎是问题的原因 - 但是......
我通过将SslProtocols 类型从SslProtocols.Tls12 更改为仅SslProtocols.Tls,成功实现了沟通。但是,据我所知,SSPI 不依赖于任何特定的 SSL 协议,那么为什么会这样呢?
目前这是一种解决方法,但我真的很想了解导致此问题的根本问题。谁能解释一下这里发生了什么?
我宁愿完全支持 TLS 1.2 而不必降级。
【问题讨论】:
-
根据 Windows 版本和在其上运行的软件,您可能支持也可能不支持 TLS 1.2。通过使用
SslProtocols.Tls,您可能让客户端/服务器协商他们可以使用的任何版本,它可能是 TLS 1.0 或 1.1,但他们找到了共同点,因为似乎至少一方无法使用 TLS 1.2 -
@PatrickMevzek 谢谢,基本上就是这样。 SSPI 在某种程度上是一个红鲱鱼,相反,我认为我应该查看 phpInfo() 中的“注册流套接字传输”详细信息。远程服务器上只列出了 'tls',但本地有 'tls, tlsv1.0, tlsv1.1, tlsv1.2'。如果你把它变成我会接受的答案。