2016-07-06 4 views
6

HTTPS에 자체 서명 된 SSL 인증서를 사용하는 서버가 있습니다. 내 응용 프로그램에 번들로 자체 서명 된 루트 인증서가 있습니다. NSURLSession을 사용하고 -URLSession:didReceiveChallenge:completionHandler: 대리자 메서드에서 SecTrustSetAnchorCertificates()을 사용하여 자체 서명 된 루트 인증서의 유효성을 검사 할 수 있습니다.HTTPS 및 자체 서명 된 서버 인증서와 함께 AVPlayer를 사용하려면 어떻게해야합니까?

그러나 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 동일합니다.

오류 도메인 = NSURLErrorDomain 코드 = -1200. "SSL 오류가 발생하여 서버에 보안 연결을 할 수 없습니다"그러나, 재생이 AVPlayerItem.error 다음으로, 조금 후에 실패 UserInfo = {NSLocalizedRecoverySuggestion = 어쨌든 서버에 연결 하시겠습니까?, NSUnderlyingError = 0x16c35720 {오류 도메인 = NSOSStatusErrorDomain 코드 = -1200 "(null)"}, NSLocalizedDescription = SSL 오류가 발생했으며 서버에 대한 보안 연결이 불가능합니다. }

AVPlayer은 SSL 핸드 셰이크를 수락 할 수 있습니까?

답변

2

이 구현은 나를 위해 일했습니다

- (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; 
} 

그러나, 내가 분별 아직 이유로 아이폰 OS 10.0.1의로 작동이 중지. 그래서 이것은 당신에게 도움이되거나 그렇지 않을 수도 있습니다. 행운을 빕니다!

+0

나는 이것이 실제로 장치에서 잘 작동한다는 것을 알았지 만 적어도 iOS 9.3.x에서는 iOS 시뮬레이터에서 이상하고 예측할 수없는 방법으로 실패 할 것입니다. 아직 iOS 10에서 테스트하지 않았습니다. –

+0

같은 문제가 있습니다. 구현이 iOS 10에서 작동하지 않고 멈추었습니다. Apple 엔지니어에게이 문제를 해결하기 위해 "기술 지원 사건"을 열었습니다. 그들이이 문제를 해결할 수 있다면 여기에 해결책을 게시 할 것입니다. – Sylverb

+0

Apple 엔지니어의 TSI에 대한 응답 : 버그 일 가능성이 높습니다. 추가 조사를 위해 레이더를 채워야합니다. – Sylverb