iOS - 接受特定的自签名证书

时间:2015-08-25 14:12:49

标签: ios objective-c certificate ssl-certificate

之前可能已经回答过,但我没有得到解决方案。

我的要求是我想以编程方式接受证书而只接受该特定证书。我只有一个只包含一个证书的rootca.pem文件。我在我的应用包中使用此文件(我正在处理类似于LinPhone 应用的应用)。

我使用此代码在我的服务器上上传文件: -

- (void)uploadImageTo:(NSURL*)url image:(UIImage*)image {

    NSString *imageName = [NSString stringWithFormat:@"%lu-%f.jpg", (unsigned long)[image hash],[NSDate timeIntervalSinceReferenceDate]];
    NSString *rawSHA = [NSString stringWithFormat:@"%@", imageName];

    // setting up the request object now
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
    [request setURL:url];
    [request setHTTPMethod:@"POST"];

    NSString *boundary = @"---------------------------14737809831466499882746641449";
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];


    //now lets create the body of the post
    NSMutableData *body = [NSMutableData data];

    // Open form
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    // Append data
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@\"\r\n",imageName] dataUsingEncoding:NSUTF8StringEncoding]];
    //[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: image/jpg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[NSData dataWithData:UIImageJPEGRepresentation(image, 1.0)]];

    //  parameter username
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"h\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[rawSHA dataUsingEncoding:NSUTF8StringEncoding]];
    //[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

    // Close form
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    [request setHTTPBody:body];
    connection = [[NSURLConnection alloc] initWithRequest:(NSURLRequest *)request delegate:self];

}

我也使用这些委托方法接受证书,但它们不起作用: -

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

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([self shouldTrustProtectionSpace:challenge.protectionSpace])
    {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    } else {
        [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
    }
}

- (BOOL)shouldTrustProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    // Load up the bundled certificate.
    NSString *certPath = [[NSBundle mainBundle] pathForResource:@"cert" ofType:@"der"];
    NSData *certData = [[NSData alloc] initWithContentsOfFile:certPath];
    CFDataRef certDataRef = ( CFDataRef)certData;
    SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef);

    // Establish a chain of trust anchored on our bundled certificate.
    CFArrayRef certArrayRef = CFArrayCreate(NULL, (void *)&cert, 1, NULL);
    SecTrustRef serverTrust = protectionSpace.serverTrust;
    SecTrustSetAnchorCertificates(serverTrust, certArrayRef);

    // Verify that trust.
    SecTrustResultType trustResult;
    SecTrustEvaluate(serverTrust, &trustResult);

    // Clean up.
    CFRelease(certArrayRef);
    CFRelease(cert);
    CFRelease(certDataRef);

    // Did our custom trust chain evaluate successfully?
    return trustResult == kSecTrustResultUnspecified;
}

我在NSLog中收到此错误: -

Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “abc.example.com” which could put your confidential information at risk." UserInfo=0x1705ac940 {NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x1704c8180>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorCodeKey=-9808, NSUnderlyingError=0x174455330 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “abc.example.com” which could put your confidential information at risk.", NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “abc.example.com” which could put your confidential information at risk., NSErrorFailingURLKey=https://abc.example.com:8443/upload.php, NSErrorFailingURLStringKey=https://abc.example.com:8443/upload.php, _kCFStreamErrorDomainKey=3}

有人可以告诉我如何以编程方式接受特定的自签名证书?

P.S: - 我对证书的了解并不是很好。

0 个答案:

没有答案