代码之家  ›  专栏  ›  技术社区  ›  Zigglzworth

iPhone上的同步SSL证书处理

  •  3
  • Zigglzworth  · 技术社区  · 15 年前

    我想知道是否有人能帮助我理解如何将SSL证书处理添加到synchronous 连接到https服务。

                    NSString *URLpath = @"https://mydomain.com/";
        NSURL *myURL = [[NSURL alloc] initWithString:URLpath];
        NSMutableURLRequest *myURLRequest = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
        [myURL release];
        [myURLRequest setHTTPMethod:@"POST"];
    
        NSString *httpBodystr = @"setting1=1";
        [myURLRequest setHTTPBody:[httpBodystr dataUsingEncoding:NSUTF8StringEncoding]];
    
        NSHTTPURLResponse* myURLResponse; 
        NSError* myError;
        NSData* myDataResult = [NSURLConnection sendSynchronousRequest:myURLRequest returningResponse:&myURLResponse error:&myError];
    
                //I guess I am meant to put some SSL handling code here
    

    非常感谢。

    3 回复  |  直到 15 年前
        1
  •  7
  •   Rob Evans anarchocurious    10 年前

    NSURLConnectionDataDelegate代理

    失败证书副本.h

    @interface FailCertificateDelegate : NSObject <NSURLConnectionDataDelegate>
       @property(atomic,retain)NSCondition *downloaded;
       @property(nonatomic,retain)NSData *dataDownloaded;
       -(NSData *)getData;
    @end
    

    失败证书副本.m

    #import "FailCertificateDelegate.h"
    
    @implementation FailCertificateDelegate
    @synthesize dataDownloaded,downloaded;
    -(id)init{
        self = [super init];
        if (self){
            dataDownloaded=nil;
            downloaded=[[NSCondition alloc] init];   
        }
        return self;
    }
    
    
    - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:    (NSURLProtectionSpace *)protectionSpace {
        NSLog(@"canAuthenticateAgainstProtectionSpace:");
        return [protectionSpace.authenticationMethod         isEqualToString:NSURLAuthenticationMethodServerTrust];
    }
    
    
    - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:    (NSURLAuthenticationChallenge *)challenge {
         NSLog(@"didReceiveAuthenticationChallenge:");
        [challenge.sender useCredential:[NSURLCredential     credentialForTrust:challenge.protectionSpace.serverTrust]     forAuthenticationChallenge:challenge];
    }
    
    
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
        [downloaded signal]; 
        [downloaded unlock];
        self.hasFinnishLoading = YES; 
    } 
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
        [dataDownloaded appendData:data];
        [downloaded lock]; 
    } 
    
    -(NSData *)getData{
        if (!self.hasFinnishLoading){
            [downloaded lock]; 
            [downloaded wait]; 
            [downloaded unlock]; 
        } 
    
        return dataDownloaded; 
    }
    
    @end
    

    为了使用它

    FailCertificateDelegate *fcd=[[FailCertificateDelegate alloc] init];
    NSURLConnection *c=[[NSURLConnection alloc] initWithRequest:request delegate:fcd startImmediately:NO];
    [c setDelegateQueue:[[NSOperationQueue alloc] init]];
    [c start];    
    NSData *d=[fcd getData];
    

    编辑:修复大数据。基于尼古拉的评论。谢谢

        2
  •  -1
  •   Community CDub    8 年前

    我也有类似的问题。在我的例子中,我有一个a-synchronous连接,它根据需要使用ssl,使用两个委托方法,允许我接受任何证书:

    - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
        return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    }
    

    但我坚持以同步的方式做同样的事情。我在网上搜索,直到找到你的帖子,不幸的是另一个 stackoverflow post 提示您不能在NSURLConnection上执行同步调用并使用ssl(因为缺少处理ssl身份验证过程的委托)。 我最后做的是得到一个HTTPRequest并使用它。这是无痛的,我花了大约一个小时来设置和它的工作完美。下面是我如何使用它。

    + (NSString *) getSynchronously:(NSDictionary *)parameters {
        NSURL *url = [NSURL URLWithString:@"https://localhost:8443/MyApp/";
        ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
        NSString *parameterJSONString = [parameters JSONRepresentation];
        [request appendPostString:parameterJSONString];
        [request addRequestHeader:@"User-Agent" value:@"MyAgent"];
        request.timeOutSeconds = CONNECTION_TIME_OUT_INTERVAL;
        [request setValidatesSecureCertificate:NO];
        [request startSynchronous];
    
        NSString *responseString = [request responseString];
        if (request.error) {
            NSLog(@"Server connection failed: %@", [request.error localizedDescription]);
        } else {
            NSLog(@"Server response: %@", responseString);
        }
    
        return responseString;
    }
    

    当然重要的是

    [request setValidatesSecureCertificate:NO];
    

    您的另一种选择是使用上述两种方法在另一个具有a-synch连接的线程中处理下载,并阻止您想要同步连接的线程,直到请求完成

        3
  •  -2
  •   Zigglzworth    15 年前

    比请张贴。

    就在排队之后:

    NSError* myError;
    

    就在队伍前面:

    NSData* myDataResult = [NSURLConnection sendSynchronousRequest:myURLRequest       
    returningResponse:&myURLResponse error:&myError];
    

        int failureCount = 0;
        NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]      
        initWithHost:@"mydomain.com" port:443 protocol:@"https"  realm:nil  
        authenticationMethod:NSURLAuthenticationMethodServerTrust];
    
        NSURLResponse *response = [[NSURLResponse alloc] initWithURL:myURL MIMEType:@"text/html" 
        expectedContentLength:-1 textEncodingName:nil]; 
    
        NSURLAuthenticationChallenge *challange = [[NSURLAuthenticationChallenge alloc] 
        initWithProtectionSpace:protectionSpace proposedCredential:[NSURLCredential 
        credentialForTrust:protectionSpace.serverTrust] previousFailureCount:failureCount 
        failureResponse:response error:myError sender:nil];