How to use NSURLConnection to connect with SSL for an untrusted cert?

后端 未结 13 1899
盖世英雄少女心
盖世英雄少女心 2020-11-22 01:29

I have the following simple code to connect to a SSL webpage

NSMutableURLRequest *urlRequest=[NSMutableURLRequest requestWithURL:url];
[ NSURLConnection send         


        
13条回答
  •  南旧
    南旧 (楼主)
    2020-11-22 01:55

    To complement the accepted answer, for much better security, you could add your server certificate or your own root CA certificate to keychain( https://stackoverflow.com/a/9941559/1432048), however doing this alone won't make NSURLConnection authenticate your self-signed server automatically. You still need to add the below code to your NSURLConnection delegate, it's copied from Apple sample code AdvancedURLConnections, and you need to add two files(Credentials.h, Credentials.m) from apple sample code to your projects.

    - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
    //        if ([trustedHosts containsObject:challenge.protectionSpace.host])
    
        OSStatus                err;
        NSURLProtectionSpace *  protectionSpace;
        SecTrustRef             trust;
        SecTrustResultType      trustResult;
        BOOL                    trusted;
    
        protectionSpace = [challenge protectionSpace];
        assert(protectionSpace != nil);
    
        trust = [protectionSpace serverTrust];
        assert(trust != NULL);
        err = SecTrustEvaluate(trust, &trustResult);
        trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified));
    
        // If that fails, apply our certificates as anchors and see if that helps.
        //
        // It's perfectly acceptable to apply all of our certificates to the SecTrust
        // object, and let the SecTrust object sort out the mess.  Of course, this assumes
        // that the user trusts all certificates equally in all situations, which is implicit
        // in our user interface; you could provide a more sophisticated user interface
        // to allow the user to trust certain certificates for certain sites and so on).
    
        if ( ! trusted ) {
            err = SecTrustSetAnchorCertificates(trust, (CFArrayRef) [Credentials sharedCredentials].certificates);
            if (err == noErr) {
                err = SecTrustEvaluate(trust, &trustResult);
            }
            trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified));
        }
        if(trusted)
            [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    }
    
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
    }
    

提交回复
热议问题