如何从iOS中的白名单接受自签名服务器证书?

前端之家收集整理的这篇文章主要介绍了如何从iOS中的白名单接受自签名服务器证书?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在NSURLConnection中接受自签名证书,正如许多人在我之前所做的那样.问题是,我只想接受我信任的证书白名单中的证书.我决心要弄清楚如何接受单一证书.这是我在NSURLConnectionDelegate中到目前为止所获得的代码
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        NSString *thePath = [[NSBundle mainBundle] pathForResource:@"trusted" ofType:@"der"];
        NSData *certData = [[NSData alloc] initWithContentsOfFile:thePath];
        CFDataRef myCertData = (__bridge_retained CFDataRef)certData;
        SecCertificateRef myCert = SecCertificateCreateWithData(NULL,myCertData);
        SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
        SecCertificateRef certArray[1] = { myCert };
        CFArrayRef myCerts = CFArrayCreate(NULL,(void *)certArray,1,NULL);
        SecTrustRef myTrust;
        OSStatus status = SecTrustCreateWithCertificates(myCerts,myPolicy,&myTrust);

        SecTrustResultType trustResult;
        if (status == noErr) {
            status = SecTrustEvaluate(myTrust,&trustResult);
        }
        BOOL trusted = NO;

        if (trustResult == kSecTrustResultUnspecified) {
            // I never get here.  Instead,trustResult is always kSecTrustResultRecoverableTrustFailure
            trusted = YES; 
        }

        if (trusted) {
            [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
                 forAuthenticationChallenge:challenge];
        } else {
            [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
        }
        CFRelease(myTrust);
        CFRelease(myCerts);
        CFRelease(myPolicy);
        CFRelease(myCert);
        CFRelease(myCertData);
    } else {
        [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
    }
}

正如您在评论中看到的那样,我实际上从未获得过kSecTrustResultUnspecified,这是我期望得到的.我验证了我的证书是正确的,并且格式正确(DER).

解决方法

好吧,想通了.事实证明,您只需要检查服务器信任,并实际使用证书数据.
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    BOOL trusted = NO;
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        NSString *thePath = [[NSBundle mainBundle] pathForResource:@"trusted" ofType:@"der"];
        NSData *certData = [[NSData alloc] initWithContentsOfFile:thePath];
        CFDataRef certDataRef = (__bridge_retained CFDataRef)certData;
        SecCertificateRef cert = SecCertificateCreateWithData(NULL,certDataRef);
        SecPolicyRef policyRef = SecPolicyCreateBasicX509();
        SecCertificateRef certArray[1] = { cert };
        CFArrayRef certArrayRef = CFArrayCreate(NULL,NULL);
        SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
        SecTrustSetAnchorCertificates(serverTrust,certArrayRef);
        SecTrustResultType trustResult;
        SecTrustEvaluate(serverTrust,&trustResult);
        trusted = (trustResult == kSecTrustResultUnspecified);
        CFRelease(certArrayRef);
        CFRelease(policyRef);
        CFRelease(cert);
        CFRelease(certDataRef);
    }
    if (trusted) {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    } else {
        [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
    }
}

猜你在找的iOS相关文章