使用 NSURLConnection 时 Mac OS 上的默认 SSLLevel 10.9 及更高版本

Default SSLLevel on Mac OS 10.9 onwards when using NSURLConnection

我们有一个遗留应用程序是根据 Mac 10.6 sdk 构建的。我们正在使用 NSURLMutableRequestNSURLConnection 进行网络调用。使用 Wireshark,我注意到在 10.9 - 10.11.2 上所有这些调用都是在 TLSv1 上进行的。在 10.11.6 之后(也是 10.13 beta) 这些是在 TLSv1.2.

上制作的

我使用 CFURLRequestSetSSLProperties(dlsym) 更改了代码以强制使用 TLSv1.2。我将 kCFStreamSSLLevel 设置为“kCFStreamSocketSecurityLevelTLSv1_2”。在这些之后,我可以看到现在可以在 TLSv1.2 上进行调用。

来自 Apple 关于 kCFStreamSSLLevel 的文档:

By default, a stream’s security level is kCFStreamSocketSecurityLevelNegotiatedSSL.

kCFStreamSocketSecurityLevelNegotiatedSSL 开始:

Specifies that the highest level security protocol that can be negotiated be set as the security protocol for a socket stream.

我知道 10.9 支持 TLSv1.2。作为测试,我将 kCFStreamSSLLevel 设置为 kCFStreamSocketSecurityLevelNegotiatedSSL 并且在 10.9 上它仍然调用 TLSv1

我有 2 个问题:

  1. 为什么在 10.9-10.11.2 的 TLSv1 上进行调用? 他们不应该自动选择可用的最高版本,即 TLSv1.2.

  2. 当使用 kCFStreamSocketSecurityLevelTLSv1_2 时,如果服务器不支持 TLSv1.2 是否会回退到较低版本或者调用会失败? 我在检查时发现了这个:

kCFStreamSocketSecurityLevelNegotiatedSSL

Discussion: Stream property value, for both set and copy operations. Indicates to use TLS or SSL with fallback to lower versions. This is what HTTPS does, for instance.

kCFStreamSocketSecurityLevelTLSv1_2甚至kCFStreamSocketSecurityLevelTLSv1都没有这样的声明。那么他们是否会回退到较低版本?

IIRC,version-specific constants 设置一个特定的版本,它不会协商任何其他版本。相比之下,协商允许它协商任何因安全问题而未被 Apple 列入黑名单的版本(例如 SSLv3)。

因此,我的回忆是,一般建议是始终在客户端使用协商,除非您需要使用特定版本来支持无法使用较新版本 [=16= 的主机] 或对于不支持正确协商的服务器,然后始终将您的服务器设置为只接受最新版本(或稍旧,如果需要支持旧客户端)。

这种方法的优点是您的客户端代码不必随着 Apple 添加新版本和弃用旧版本而更改,并且服务器可能在您的直接控制之下,因此您可以随时更改它而无需强制您的用户下载软件更新。