【问题标题】:SSL/TLS errors using cURL (PHP) with a C# REST API and the SslStream class使用带有 C# REST API 和 SslStream 类的 cURL (PHP) 的 SSL/TLS 错误
【发布时间】: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'。如果你把它变成我会接受的答案。

标签: c# php ssl curl


【解决方案1】:

该问题实际上与 SSPI 无关。

SslProtocols.Tls 可能意味着:“自动协商任何合适的通用版本”,而 SslProtocols.Tls12 意味着:“强制 TLS 版本 1.2”

因此,如果您强制使用 TLS 1.2 但并非所有各方都知道此版本,那么握手将失败。 通过让他们自动协商,他们可能能够收敛到 TLS 1.1 或 1.0

请注意,现在除了 TLS 1.2 之外的任何东西都不是一个好主意,或者至少它应该是暂时的情况。两周前,TLS 1.3 刚刚作为标准发布。

让系统自动协商版本通常会更好,这样当它们升级时,它们会落入当时可能的最高版本。所以强制SslProtocols.Tls12 即使它起作用了,在短期内会很好(目前最好的 TLS 版本),但从长远来看(如果你的两个系统都升级并且将来能够支持 TLS 1.3,你不会从中获利,这是可悲的,因为 1.3 在许多方面都优于 1.2)。

但是,相反,让他们自动协商有一些缺点:

  1. 虽然主要是装饰性的,但 OpenSSL 中用于进行这种自动协商的符号常量被非常误导地称为 SSLv23_METHOD(例如,您也有 TLSv1_2_METHOD),这确实意味着 SSL 2 或SSL 3(现在应该死的两件事)但是“我们可以自动协商最好的”(关于正确设计和使用 TLS API 的一般问题,特别是在网络之外,这是一篇令人大开眼界的论文:https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf
  2. 更重要的是,如果您不注意正在发生的事情(日志记录),您可以让系统自动协商非常低的版本,如 TLS 1.0 或更差的 SSL 3.0,但同时您还需要更好的东西。因此,您可能有一个正在运行的系统,但没有达到您想要或需要的安全级别。

【讨论】:

    猜你喜欢
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 2016-05-04
    • 2014-10-02
    • 1970-01-01
    • 2013-02-03
    • 2010-10-18
    相关资源
    最近更新 更多