我从NSString#stringWithContentsOfURL:
的服务器请求一些数据。服务器使用的是自签名证书,因此stringWithContentsOfURL:
只返回nil,并且不会更改以接受证书。
这是所有预期的行为。我知道如何使用NSURLConnection
和它的委托方法正确地执行此操作,但我正在寻找一个较短期的修复而不是重写此代码。 (Yay截止日期)
所以我的问题是,是否可以将自签名证书导入应用程序的钥匙串,这会导致stringWithContentsOfURL:
接受自签名证书吗?
答案 0 :(得分:1)
我相信Apple有一个企业工具用于安装SSL证书 - 有必要让Exchange邮件正常工作。
您也可以将.cer文件邮寄给自己,在iPhone上打开并安装。
还有来自Apple的AdvancedURLConnections sample project
此示例演示了各种 先进的网络技术 NSURLConnection的。具体来说,它 演示了如何回应 身份验证挑战,如何 修改默认服务器信任 评估(例如,支持a 服务器带有自签名 证书),以及如何提供 客户身份。
答案 1 :(得分: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;
如果我愿意的话,我想我只能拨打一个电话。