您的位置:首页 > 理论基础 > 计算机网络

HTTPS 证书处理 objective-c实现

2015-07-02 14:30 561 查看
前一篇文章用c#处理了证书,这次就使用oc来试一下,其实基本原理累似,一般都是自己覆盖几个函数,然后自己处理证书相关的东西。

自己创建一个类,如:

@interface MyURLConnection : NSObject<NSURLConnectionDelegate, NSURLConnectionDataDelegate>

- (void) sendPostRequest: (NSURL*)url postData: (NSData*)postData;

@end
我比较喜欢把一些不需要对外公开的成员放在extension里面,省的别人看见。
@interface MyURLConnection()
{
NSURLConnection*    _conn;
NSMutableData*      _receivedData;
BOOL                _success;
}

@end


然后实现sendPostRequest函数:

-(void) sendPostRequest:(NSURL *)url postData:(NSData *)postData
{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:@"POST"];
NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"text/plain, charset=UTF-8" forHTTPHeaderField:@"Content-Type"];

[request setHTTPBody:postData];

//    NSLog(@"all headers: %@", request.allHTTPHeaderFields);

_conn = [NSURLConnection connectionWithRequest:request delegate:self];

[_conn start];

_receivedData = nil;
_success = NO;
}
实现NSURLConnection的几个delegate函数:(上面的NSURLConnection操作是异步的)

- (void)connection: (NSURLConnection*) connection didReceiveResponse:(NSURLResponse *)response
{
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode != 200) {
NSLog(@"%s failed status code %ld", __FUNCTION__, (long)statusCode);
_success = NO;
}
else
{
_success = YES;
}
}

_receivedData = nil;
}

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if (!_receivedData) {
_receivedData = [[NSMutableData alloc] initWithData:data];
}
else
{
[_receivedData appendData:data];
}
}

- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString* data = [[NSString alloc] initWithData:_receivedData encoding:NSUTF8StringEncoding];
//    NSLog(@"NXURlConnection, finished loading: %@", data);

NSError* err = nil;
if (!_success) {
err = [[NSError alloc] initWithDomain:@"https access failed" code:1 userInfo:nil];
}
else
{
// success
}
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
_success = NO;
NSLog(@"NXURLConnection error: %@", [error localizedDescription]);
}

- (void) connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSLog(@"willSendRequestForAuthentiationChallenge: %@", challenge.protectionSpace.authenticationMethod);
if ([challenge.protectionSpace.authenticationMethod isEqualToString: NSURLAuthenticationMethodServerTrust]) {
NSLog(@"cert host: %@", challenge.protectionSpace.host);

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

前面几个函数从字面意思就可以知道是对访问的一些处理,比如成功失败什么的。关键是最后一个函数。

这个函数里面可以处理证书相关的东西,比如获取证书信息等,上面的例子是无论什么证书,都通过。当然我们也可以根据具体的证书信息做一些判断,比如不是公司自己的证书,就取消操作什么的。

调用:

MyURLConnection* conn = [[MyURLConnection alloc]init];

[conn sendPostRequest:@"https://xxxxx" postData:@"test"];


这样,就算测试站点的证书是自己创建的测试证书,也可以成功访问到数据了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  https 证书