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

iOS访问https ssl和tls双向加密

2016-06-12 08:51 489 查看
转载:http://blog.csdn.net/woaifen3344/article/details/41145729

关于https和ssl的原理,请到此处查看:http://blog.163.com/magicc_love/blog/static/185853662201321423527263/

由于项目需求,访问服务是https的,并且使用的是ssl加密方式

下面说明使用MKNetworkit网络库实现的代码:

[objc] view
plain copy

 print?





- (void)testClientCertificate {  

  SecIdentityRef identity = NULL;  

  SecTrustRef trust = NULL;  

  NSString *p12 = [[NSBundle mainBundle] pathForResource:@"testClient" ofType:@"p12"];  

  NSData *PKCS12Data = [NSData dataWithContentsOfFile:p12];  

    

  [[self class] extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data];  

    

  NSString *url = @"https://218.244.131.231/ManicureShop/api/order/pay/%@";  

  NSDictionary *dic = @{@"request" : @{  

                            @"orderNo" : @"1409282102222110030643",  

                            @"type" : @(2)  

                            }  

                        };  

    

  _signString = nil;  

  NSData *postData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];  

  NSString *sign = [self signWithSignKey:@"test" params:dic];  

  NSMutableData *body = [postData mutableCopy];  

  NSLog(@"%@", [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding]);  

  url = [NSString stringWithFormat:url, sign];  

    

  MKNetworkEngine *engine = [[MKNetworkEngine alloc] initWithHostName:@"218.244.131.231"];  

  MKNetworkOperation *op = [engine operationWithPath:[NSString stringWithFormat:@"/ManicureShop/api/order/pay/%@", sign] params:dic httpMethod:@"POST" ssl:YES];  

  op.postDataEncoding = MKNKPostDataEncodingTypeJSON; // 传JOSN  

    

  // 这个是app bundle 路径下的自签证书  

  op.clientCertificate = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"testClient.p12"];  

  // 这个是自签证书的密码  

  op.clientCertificatePassword = @"testHttps";  

    

  // 由于自签名的证书是需要忽略的,所以这里需要设置为YES,表示允许  

  op.shouldContinueWithInvalidCertificate = YES;  

  [op addCompletionHandler:^(MKNetworkOperation *completedOperation) {  

    NSLog(@"%@", completedOperation.responseJSON);  

  } errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {  

    NSLog(@"%@", [error description]);  

  }];  

    

  [engine enqueueOperation:op];  

  return;  

}  

// 下面这段代码是提取和校验证书的数据的

[objc] view
plain copy

 print?





+ (BOOL)extractIdentity:(SecIdentityRef *)outIdentity andTrust:(SecTrustRef*)outTrust fromPKCS12Data:(NSData *)inPKCS12Data {  

  OSStatus securityError = errSecSuccess;  

    

  // 证书密钥  

  NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:@"testHttps"  

                                                                forKey:(__bridge id)kSecImportExportPassphrase];  

    

  CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);  

  securityError = SecPKCS12Import((__bridge CFDataRef)inPKCS12Data,(__bridge CFDictionaryRef)optionsDictionary,&items);  

    

  if (securityError == 0) {  

    CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);  

    const voidvoid *tempIdentity = NULL;  

    tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);  

    *outIdentity = (SecIdentityRef)tempIdentity;  

    const voidvoid *tempTrust = NULL;  

    tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);  

    *outTrust = (SecTrustRef)tempTrust;  

  } else {  

    NSLog(@"Failed with error code %d",(int)securityError);  

    return NO;  

  }  

  return YES;  

}  

下面说明一下使用AFNetworking网络库访问的方式:

[objc] view
plain copy

 print?





- (void)testClientCertificate {  

  SecIdentityRef identity = NULL;  

  SecTrustRef trust = NULL;  

  NSString *p12 = [[NSBundle mainBundle] pathForResource:@"testClient" ofType:@"p12"];  

  NSData *PKCS12Data = [NSData dataWithContentsOfFile:p12];  

    

  [[self class] extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data];  

    

  NSString *url = @"https://218.244.131.231/ManicureShop/api/order/pay/%@";  

  NSDictionary *dic = @{@"request" : @{  

                            @"orderNo" : @"1409282102222110030643",  

                            @"type" : @(2)  

                            }  

                        };  

    

  _signString = nil;  

  NSData *postData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];  

  NSString *sign = [self signWithSignKey:@"test" params:dic];  

  NSMutableData *body = [postData mutableCopy];  

  NSLog(@"%@", [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding]);  

  url = [NSString stringWithFormat:url, sign];  

    

  AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];  

  manager.requestSerializer = [AFJSONRequestSerializer serializer];  

  manager.responseSerializer = [AFJSONResponseSerializer serializer];  

  [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];  

  [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];  

  manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"application/json", @"text/plain"]];  

  manager.securityPolicy = [self customSecurityPolicy];  

    

  [manager POST:url parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject) {  

    NSLog(@"JSON: %@", responseObject);  

  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {  

      

    NSLog(@"Error: %@", error);  

  }];  

}  

下面这段代码是处理SSL安全性问题的:

[objc] view
plain copy

 print?





/**** SSL Pinning ****/  

- (AFSecurityPolicy*)customSecurityPolicy {  

  NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"testClient" ofType:@"cer"];  

  NSData *certData = [NSData dataWithContentsOfFile:cerPath];  

  AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];  

  [securityPolicy setAllowInvalidCertificates:YES];  

  [securityPolicy setPinnedCertificates:@[certData]];  

  [securityPolicy setSSLPinningMode:AFSSLPinningModeCertificate];  

  /**** SSL Pinning ****/  

  return securityPolicy;  

}  

为了实现访问https tls加密方式,我也费了不少时间来查,这里写下此文章,希望对大家有用!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: