1

我正在从服务器请求一些数据NSString#stringWithContentsOfURL:。服务器正在使用自签名证书,因此stringWithContentsOfURL:只需返回 nil 并且不提供更改以接受证书。

这都是预期的行为。我知道如何正确地使用NSURLConnection它的委托方法来执行此操作,但我正在寻找更短期的修复而不是重写此代码。(是的最后期限)

所以我的问题是,是否可以将自签名证书导入应用程序的钥匙串,这会导致stringWithContentsOfURL:接受自签名证书吗?

4

2 回答 2

1

我相信 Apple 提供了一个用于安装 SSL 证书的企业工具——它是让交换邮件正常工作所必需的。

您也可以将 .cer 文件邮寄给自己,在 iPhone 上打开并安装它。

还有来自 Apple的AdvancedURLConnections 示例项目

此示例演示了使用 NSURLConnection 的各种高级网络技术。具体来说,它演示了如何响应身份验证挑战、如何修改默认服务器信任评估(例如,支持具有自签名证书的服务器)以及如何提供客户端身份。

于 2010-09-21T11:03:43.590 回答
1

没有办法绕过那个 SSL 验证方案,经过一段时间的尝试和到处寻找解决方案后,我不得不实现一个类来做到这一点。

由于 NSString 的 stringWithContentsOfURL 的优势是同步的,我必须确保我的也是同步的。对于每个目的,它可能有点大,但你明白了它的要点。

@interface NZStringLoader : NSObject
@property (assign, readonly, nonatomic) BOOL done;
@property (strong, readonly, nonatomic) NSString *result;
@property (strong, readonly, nonatomic) NSURLConnection *conn;

- (id) initWithURL:(NSURL*)u;
- (void) loadSynchronously;

@end

@implementation NZStringLoader

@synthesize done = _done, result = _result, conn = _connection;

- (id) initWithURL:(NSURL*)u {
    NSURLRequest *req = [[NSURLRequest alloc] initWithURL:u
                                              cachePolicy:NSURLRequestReloadIgnoringCacheData
                                          timeoutInterval:10.0];
    _connection = [NSURLConnection connectionWithRequest:req delegate:self];
    _done = NO;

    return self;
}

- (void) loadSynchronously {
    [_connection start];

    while(!_done)
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.15]];
}

#pragma mark -
#pragma mark NSURLConnectionDelegate

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    _done = YES;
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    RTLog(@"%@", [error localizedDescription]);
    _done = YES;
}

- (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])
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    if(_result == nil)
        _result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    else
        _result = [_result stringByAppendingString:[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]];
}

@end

它是这样使用的:

    NZStringLoader *sl = [[NSStringLoader alloc] initWithURL:u];
    [sl loadSynchronously];
    result = sl.result;

如果我愿意,我想我可以只打一个电话。

于 2012-04-07T16:36:21.030 回答