使用 NSURLConnection 时 Mac OS 上的默认 SSLLevel 10.9 及更高版本
Default SSLLevel on Mac OS 10.9 onwards when using NSURLConnection
我们有一个遗留应用程序是根据 Mac 10.6 sdk 构建的。我们正在使用 NSURLMutableRequest
和 NSURLConnection
进行网络调用。使用 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 个问题:
为什么在 10.9-10.11.2 的 TLSv1 上进行调用? 他们不应该自动选择可用的最高版本,即 TLSv1.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 添加新版本和弃用旧版本而更改,并且服务器可能在您的直接控制之下,因此您可以随时更改它而无需强制您的用户下载软件更新。
我们有一个遗留应用程序是根据 Mac 10.6 sdk 构建的。我们正在使用 NSURLMutableRequest
和 NSURLConnection
进行网络调用。使用 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 个问题:
为什么在 10.9-10.11.2 的 TLSv1 上进行调用? 他们不应该自动选择可用的最高版本,即 TLSv1.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 添加新版本和弃用旧版本而更改,并且服务器可能在您的直接控制之下,因此您可以随时更改它而无需强制您的用户下载软件更新。