最近在做一個用AVplayer播放HTTPSURL锦针,一直實現(xiàn)不了,最后用WKWebView實現(xiàn)的置蜀,但是需要證書的各種驗證奈搜,這里把代碼貼出來,以供大家參考盯荤。有什么不足的歡迎大家再補充馋吗。
雙向驗證:
- (void)webView:(WKWebView*)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge completionHandler:(void(^)(NSURLSessionAuthChallengeDispositiondisposition,NSURLCredential*_Nullablecredential))completionHandler{ ? ?NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
? ? NSURLCredential*credential =nil;
? ? // 服務(wù)器驗證
? ? if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
? ? {
//? ? ? ? /* 調(diào)用自定義的驗證過程 */
? ? ? ? if([selfmyCustomValidation:challenge]) {
? ? ? ? ? ? credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
? ? ? ? ? ? if(credential) {
? ? ? ? ? ? ? ? disposition =NSURLSessionAuthChallengeUseCredential;
? ? ? ? ? ? }
? ? ? ? }else{
? ? ? ? ? ? /* 無效的話,取消 */
? ? ? ? ? ? disposition =NSURLSessionAuthChallengeCancelAuthenticationChallenge;
? ? ? ? }
? ? }else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate])
? ? {//客戶端認(rèn)證
? ? ? ? NSString *thePath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"];
? ? ? ? NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
? ? ? ? CFDataRefinPKCS12Data = (CFDataRef)CFBridgingRetain(PKCS12Data);
? ? ? ? SecIdentityRefidentity;
? ? ? ? // 讀取p12證書中的內(nèi)容
? ? ? ? OSStatusresult = [selfextractP12Data:inPKCS12DatatoIdentity:&identity];
? ? ? ? if(result !=errSecSuccess){
? ? ? ? ? ? completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? SecCertificateRefcertificate =NULL;
? ? ? ? SecIdentityCopyCertificate(identity, &certificate);
? ? ? ? constvoid*certs[] = {certificate};
? ? ? ? CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL);
? ? ? ? credential = [NSURLCredential credentialWithIdentity:identity certificates:(NSArray*)CFBridgingRelease(certArray) persistence:NSURLCredentialPersistencePermanent];
? ? ? ? if(credential) {
? ? ? ? ? ? disposition =NSURLSessionAuthChallengeUseCredential;
? ? ? ? }
? ? }
? ? if(completionHandler) {
? ? ? ? completionHandler(disposition, credential);
? ? }
}
-(OSStatus) extractP12Data:(CFDataRef)inP12Data toIdentity:(SecIdentityRef*)identity {
? ? OSStatussecurityError =errSecSuccess;
? ? CFStringRefpassword =CFSTR("123456");//證書密碼
? ? const void *keys[] = { kSecImportExportPassphrase };
? ? constvoid*values[] = { password };
? ? CFDictionaryRefoptions =CFDictionaryCreate(NULL, keys, values,1,NULL,NULL);
? ? CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
? ? securityError =SecPKCS12Import(inP12Data, options, &items);
? ? if(securityError ==0) {
? ? ? ? CFDictionaryRef ident = CFArrayGetValueAtIndex(items,0);
? ? ? ? constvoid*tempIdentity =NULL;
? ? ? ? tempIdentity =CFDictionaryGetValue(ident, kSecImportItemIdentity);
? ? ? ? *identity = (SecIdentityRef)tempIdentity;
? ? }
? ? if(options) {
? ? ? ? CFRelease(options);
? ? }
? ? returnsecurityError;
}
- (BOOL)myCustomValidation:(NSURLAuthenticationChallenge*)challenge
{
? ? //獲取trust object
? ? SecTrustRef trust = challenge.protectionSpace.serverTrust;
? ? SecTrustResultType result;
? ? //導(dǎo)入證書
? ? NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"serverShuang" ofType:@"der"];; //證書的路徑
? ? NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
? ? SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(cerData));
? ? NSMutableArray*trustedCertificates = [NSMutableArraynew];
? ? [trustedCertificatesaddObject:(__bridge_transferid)(certificate)];
//? ? trustedCertificates = @[CFBridgingRelease(certificate)];
? ? //注意:這里將之前導(dǎo)入的證書設(shè)置成下面驗證的Trust Object的anchor certificate
? ? SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)trustedCertificates);
? ? //2)SecTrustEvaluate會查找前面SecTrustSetAnchorCertificates設(shè)置的證書或者系統(tǒng)默認(rèn)提供的證書秋秤,對trust進(jìn)行驗證
? ? OSStatusstatus =SecTrustEvaluate(trust, &result);
? ? if(status ==errSecSuccess&&
? ? ? ? (result ==kSecTrustResultProceed ||
?? ? ? ? result ==kSecTrustResultUnspecified)){//強制過
? ? ? ? ? ? returnYES;
? ? ? ? }
? ? return NO;
}
單向驗證:
- (void)webView:(WKWebView*)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge completionHandler:(void(^)(NSURLSessionAuthChallengeDispositiondisposition,NSURLCredential*_Nullablecredential))completionHandler{
//單向證書驗證
//? ? SecTrustRef servertrust = challenge.protectionSpace.serverTrust;
//
//? ? SecCertificateRef certi= SecTrustGetCertificateAtIndex(servertrust, 0);
//
//? ? NSData *certidata = CFBridgingRelease(CFBridgingRetain(CFBridgingRelease(SecCertificateCopyData(certi))));
//
//? ? NSString *path = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"der"];
//
//? ? NSData *localCertiData = [NSData dataWithContentsOfFile:path];
//
//? ? if ([certidata isEqualToData:localCertiData]) {
//
//? ? ? ? NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:servertrust];
//
//? ? ? ? [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
//
//? ? ? ? completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
//
//? ? ? ? NSLog(@"服務(wù)端證書認(rèn)證通過");
//
//? ? }else {
//
//? ? ? ? completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
//
//? ? ? ? NSLog(@"服務(wù)端認(rèn)證失敗");
//
//? ? }
}
證書全部信任:
- (void)webView:(WKWebView*)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge completionHandler:(void(^)(NSURLSessionAuthChallengeDispositiondisposition,NSURLCredential*_Nullablecredential))completionHandler{
?//全部信任
//? ? if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
//
//? ? ? ? NSURLCredential *credential = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
//
//? ? ? ? completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
//
//? ? }
}