NSRequiresCertificateTransparency = YES使iOS 9模拟器

时间:2017-01-28 22:10:04

标签: ios ios-simulator ios9 app-transport-security nsapptransportsecurity

我正在尝试从App Transport Security为我的ios应用启用NSRequiresCertificateTransparency标记以获得更好的安全性。我测试了它在iOS 10的设备和iOS 10的模拟器中工作正常。但它使得https连接在iOS 9.3的模拟器中失败。如果我只是关闭这个特定的标志,它就会再次运作。

问题不在我连接的服务器上,因为我甚至可以使用www.apple.com重现它。以下是我使用的Info.plist中的设置:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>www.apple.com</key>
        <dict>
            <key>NSRequiresCertificateTransparency</key>
            <true/>
        </dict>
    </dict>
</dict>

以下是代码:

NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"https://www.apple.com/"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (error) {
        NSLog(@"fail");
    }
}];
[task resume];

我在日志中看到的错误是: NSURLSession / NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9802)

也许它只发生在iOS 9的模拟器中?不幸的是,我没有手持iOS 9的设备来测试它。

更新

设置CFNETWORK_DIAGNOSTICS = 3 env变量后,我在日志中看不到任何帮助。以下是关于错误的部分:

    Response Error
    Request: <CFURLRequest 0x7f8d0f668d00 [0x108314a40]> {url = https://www.apple.com/, cs = 0x0}
      Error: Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x7f8d0f590a80>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=<CFArray 0x7f8d0f50dfb0 [0x108314a40]>{type = immutable, count = 2, values = (
                0 : <cert(0x7f8d0f66ef10) s: www.apple.com i: Symantec Class 3 EV SSL CA - G3>
                1 : <cert(0x7f8d0f637e60) s: Symantec Class 3 EV SSL CA - G3 i: VeriSign Class 3 Public Primary Certification Authority - G5>
             )}}
    } [3:22]
Jan 31 17:09:13  test2[34612] <Notice>: CFNetwork Diagnostics [3:23] 17:09:13.125 {
               Did Fail
                 Loader: <CFURLRequest 0x7f8d0f737670 [0x108314a40]> {url = https://www.apple.com/, cs = 0x0}
                  Error: Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x7f8d0f590a80>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=<CFArray 0x7f8d0f50dfb0 [0x108314a40]>{type = immutable, count = 2, values = (
                            0 : <cert(0x7f8d0f66ef10) s: www.apple.com i: Symantec Class 3 EV SSL CA - G3>
                            1 : <cert(0x7f8d0f637e60) s: Symantec Class 3 EV SSL CA - G3 i: VeriSign Class 3 Public Primary Certification Authority - G5>
                         )}}
    init to origin load: 0.00299901s
             total time: 0.156503s
            total bytes: 0
    } [3:23]

更新2:

以下是调试器中错误对象的视图。

enter image description here

1 个答案:

答案 0 :(得分:2)

在iOS 10中引入了NSRequiresCertificateTransparency密钥,所以我不确定为什么会失败。由于iOS9不会检查它,因此绝对不会因证书透明度而失败,但iOS 10会(因为iOS 10会理解NSRequiresCertificateTransparency密钥)。

我确实在运行iOS 9的物理设备上确认此操作失败。但它并非对所有服务器都失败。例如,www.google.com可以在模拟器和物理设备上使用iOS 9。

我建议打开ATS详细网络日志记录,以确定SSL故障是由您的ATS配置引起的,还是其他内容发生故障。详细了解如何启用详细日志记录here。我怀疑还有另一个错误导致SSL错误。

此外,从info.plist中删除与App Transport Security相关的所有条目,并查看它是否在iOS 9中有效。至少将设置作为根本原因。

我能想到的唯一另一件事是,iOS9因为你有一个没有效果的异常域(就iOS 9而言)而言很困惑,尽管我怀疑这是它。也许在apple.com异常域条目下添加值为false的NSAllowsArbitraryLoads密钥。

我建议关闭标志,直到您不再需要支持iOS 9设备。