web-dev-qa-db-ja.com

NSURLConnectionでの証明書エラーの無視

このエラーが発生します

The certificate for this server is invalid. You might be connecting to a server
that is pretending to be "server addres goes here" which could put your
confidential information at risk."

私はこの方法を使用しています:

[NSURLConnection sendSynchronousRequest:request
                      returningResponse:&response
                                  error:&error];

どうすればこれを修正できますか?

私はこのコードを試しました:

 NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
                                                               delegate:self];

しかし、didReceiveResponseメソッドでEXC_BAD_ACCESSを取得します。

19
Ideveloper

機密情報を送信していない場合は、無効な証明書を単に無視することができます。 この記事 それを行う方法を説明します。これは、その記事で説明されているメソッドの1つに対する Alexandre Colucci による実装例です。

基本的に、@implementationのすぐ上にダミーインターフェイスを定義する必要があります。

@interface NSURLRequest (DummyInterface)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)Host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)Host;
@end

そして、sendSynchronousRequestを呼び出す前に、ダミーインターフェイスで定義したプライベートメソッドを呼び出します。

[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[URL Host]];
17
William Niu

新しいものを使用した正しい(非推奨ではない、プライベートではない)方法:

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

Appleが指定したメソッドはNSURLConnectionDelegatesに使用する必要があります)は、保護スペースに提供された資格情報を使用してServerTrustメソッドに応答します(これにより、次の接続が可能になります。

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        NSLog(@"Ignoring SSL");
        SecTrustRef trust = challenge.protectionSpace.serverTrust;
        NSURLCredential *cred;
        cred = [NSURLCredential credentialForTrust:trust];
        [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
        return;
    }

    // Provide your regular login credential if needed...
}

このメソッドを使用してログインしたくない場合は、使用可能な認証メソッドごとに1回、このメソッドが複数回呼び出されます。

 [challenge.sender rejectProtectionSpaceAndContinueWithChallenge:challenge];
16
BadPirate

私も同様の問題を抱えていました。以下のコードスニペットを使用して解決しました:

-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {

    NSLog(@"This will execute successfully!");
    if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodServerTrust) {

        [[challenge sender] useCredential:[NSURLCredential credentialForTrust:[[challenge protectionSpace] serverTrust]] forAuthenticationChallenge:challenge];
    }
}

以下のメソッドは非推奨であるため:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)space { ... }

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { ... }
5

デリゲートをselfとして設定したので、そのリクエストを送信するクラスにNSURLConnectionDelegateの一部を実装することで、これを修正できます。

これを実装します:

-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;

これを行うことによって:

[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];

注:これは、本番環境で使用するソリューションではありません。証明書が存在するのには理由があります! :)

3
William Power

これは、「エラーを無視する方法」という質問には答えません。それは無責任です。

むしろ、サーバーを認証するCAをロードして、接続を期待どおりに続行できるようにする方法を示しています。以下では、CAはアプリにバンドルされており、ca-cert.derと呼ばれます。そのDER(PEMではなく)でエンコードされた証明書。

また、Appleの テクニカルノートTN2232 HTTPSサーバーの信頼性評価 もご覧ください。 kSecTrustResultUnspecifiedは成功です。 テクニカルQ&A QA1360 kSecTrustResultUnspecifiedエラーの説明 を参照してください。

-(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:
(NSURLProtectionSpace*)space
{        
    return [[space authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:
(NSURLAuthenticationChallenge *)challenge
{        
    if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust])
    {
        do
        {
            SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
            NSCAssert(serverTrust != nil, @"serverTrust is nil");
            if(nil == serverTrust)
                break; /* failed */

            NSData* caCert = [NSData dataWithContentsOfFile:@"ca-cert.der"];
            NSCAssert(caCert != nil, @"caCert is nil");
            if(nil == caCert)
                break; /* failed */

            SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCert);
            NSCAssert(caRef != nil, @"caRef is nil");
            if(nil == caRef)
                break; /* failed */

            NSArray* caArray = [NSArray arrayWithObject:(__bridge id)(caRef)];
            NSCAssert(caArray != nil, @"caArray is nil");
            if(nil == caArray)
                break; /* failed */

            OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);
            NSCAssert(errSecSuccess == status, @"SecTrustSetAnchorCertificates failed");
            if(!(errSecSuccess == status))
                break; /* failed */

            SecTrustResultType result = -1;
            status = SecTrustEvaluate(serverTrust, &result);
            if(!(errSecSuccess == status))
                break; /* failed */

            NSLog(@"Result: %d", result);

            /* This test looks for a "SUCCESS" */
            /* kSecTrustResultUnspecified and kSecTrustResultProceed are success */
            if(result != kSecTrustResultUnspecified && result != kSecTrustResultProceed)
                break; /* failed */

#if 0
            /* Alternate test looks for a "NOT FAILURE" */
            /* Treat kSecTrustResultConfirm and kSecTrustResultRecoverableTrustFailure as success */
            /*   since the user will likely tap-through to see the dancing bunnies */
            if(result == kSecTrustResultDeny || result == kSecTrustResultFatalTrustFailure || result == kSecTrustResultOtherError)
                break; /* failed to trust cert (good in this case) */
#endif

            // The only good exit point
            return [[challenge sender] useCredential: [NSURLCredential credentialForTrust: serverTrust]
                          forAuthenticationChallenge: challenge];

        } while(0);
    }

    // Bad dog
    return [[challenge sender] cancelAuthenticationChallenge: challenge];
}
3
jww

HTTPSURLを使用していますか。その場合は、ブラウザのURLに移動して、証明書を確認してください。証明書が使用しようとしているドメインまたはサブドメインに対して有効であること、およびすべての中間証明書がサーバーにインストールされていることを確認してください。これと同様の問題が発生しました。解決策は、中間証明書をインストールすることでした。

1
Jonathan