【问题标题】:How can I use an AVPlayer with HTTPS and self-signed server certificates?如何使用带有 HTTPS 和自签名服务器证书的 AVPlayer?
【发布时间】:2016-11-08 02:58:38
【问题描述】:

我有一台使用自签名 SSL 证书进行 HTTPS 的服务器。我将自签名根证书捆绑到我的应用程序中。通过在-URLSession:didReceiveChallenge:completionHandler: 委托方法中使用SecTrustSetAnchorCertificates(),我可以让NSURLSession 使用和验证自签名根证书。

但是,当我使用 AVPlayer 尝试此操作时,我收到 SSL 错误并且播放失败。这是我的AVAssetResourceLoader 委托实现:

- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForResponseToAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([challenge.protectionSpace.authenticationMethod isEqual:NSURLAuthenticationMethodServerTrust]) {
        SecTrustRef trust = challenge.protectionSpace.serverTrust;
        SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)self.secTrustCertificates);

        SecTrustResultType trustResult = kSecTrustResultInvalid;
        OSStatus status = SecTrustEvaluate(trust, &trustResult);

        if (status == errSecSuccess && (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed)) {
            [challenge.sender useCredential:[NSURLCredential credentialForTrust:trust] forAuthenticationChallenge:challenge];
            return YES;
        } else {
            [challenge.sender cancelAuthenticationChallenge:challenge];
            return YES;
        }
    }
    return NO;
}

委托被调用,trustResult 等于kSecTrustResultUnspecified(意思是“受信任,没有明确的用户覆盖”),正如预期的那样。但是,播放很快就会失败,出现以下AVPlayerItem.error

Error Domain=NSURLErrorDomain Code=-1200 “发生 SSL 错误,无法与服务器建立安全连接。” UserInfo={NSLocalizedRecoverySuggestion=您还是要连接到服务器吗?, NSUnderlyingError=0x16c35720 {Error Domain=NSOSStatusErrorDomain Code=-1200 "(null)"}, NSLocalizedDescription=发生 SSL 错误,无法与服务器建立安全连接制作完成。}

如何让AVPlayer 接受 SSL 握手?

【问题讨论】:

    标签: ios objective-c https ssl-certificate self-signed


    【解决方案1】:

    这个实现对我有用:

    - (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader
    shouldWaitForResponseToAuthenticationChallenge:(NSURLAuthenticationChallenge *)authenticationChallenge
    {
        //server trust
        NSURLProtectionSpace *protectionSpace = authenticationChallenge.protectionSpace;
        if ([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
            [authenticationChallenge.sender useCredential:[NSURLCredential credentialForTrust:authenticationChallenge.protectionSpace.serverTrust] forAuthenticationChallenge:authenticationChallenge];
            [authenticationChallenge.sender continueWithoutCredentialForAuthenticationChallenge:authenticationChallenge];
        }
        else { // other type: username password, client trust...
        }
        return YES;
    }
    

    但是,它从 iOS 10.0.1 起停止工作,原因我还不清楚。因此,这可能对您有帮助,也可能对您没有帮助。祝你好运!

    【讨论】:

    • 从那以后我发现这实际上在设备上运行良好,但它会以奇怪和不可预测的方式失败在 iOS 模拟器中,至少在 iOS 9.3 中。 X。我还没有在 iOS 10 上测试过。
    • 同样的问题,我的实现停止与 iOS 10 一起工作,我确实打开了一个“技术支持事件”来尝试与一些 Apple 工程师解决这个问题。如果他们设法解决了这个问题,我会在这里发布解决方案。
    • Apple 工程师对我的 TSI 的回应:这可能是一个错误,我必须填充雷达以进一步调查。
    • @Sylverb 你找到解决这个问题的方法了吗?
    • @UtsavDusad 我用过一个 TSI,与工程师核实,在确认它不起作用后,他所做的只是我开一张没有担保的票,它会在一天之内解决...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 2016-07-10
    • 2019-07-26
    • 2016-07-17
    • 1970-01-01
    • 2010-12-11
    • 2012-02-17
    相关资源
    最近更新 更多