iOS访问https ssl和tls双向加密

简介:

文章已经移到此处:http://www.henishuo.com/ios-https-tls-ssl/



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


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

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

- (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;
}


// 下面这段代码是提取和校验证书的数据的
+ (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 void *tempIdentity = NULL;
    tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);
    *outIdentity = (SecIdentityRef)tempIdentity;
    const void *tempTrust = NULL;
    tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
    *outTrust = (SecTrustRef)tempTrust;
  } else {
    NSLog(@"Failed with error code %d",(int)securityError);
    return NO;
  }
  return YES;
}




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

- (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安全性问题的:

/**** 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加密方式,我也费了不少时间来查,这里写下此文章,希望对大家有用!

目录
相关文章
|
8天前
|
安全 算法 网络安全
HTTPS 的加密流程
HTTPS (Hyper Text Transfer Protocol Secure) 是基于 HTTP 协议之上的安全协议,用于在客户端和服务器之间通过互联网传输数据的加密和身份验证。它使用 SSL/TLS (Secure Sockets Layer/Transport Layer Security) 协议来保护数据的安全性,可以防止数据被窃听、篡改或伪造。
26 3
|
12天前
|
安全 网络协议 应用服务中间件
一文读懂HTTPS⭐揭秘加密传输背后的原理与Nginx配置攻略
一文读懂HTTPS⭐揭秘加密传输背后的原理与Nginx配置攻略
|
12天前
|
安全 Go 网络安全
【Go语言专栏】Go语言中的HTTPS与TLS配置
【4月更文挑战第30天】本文介绍了在Go语言中配置HTTPS服务器和处理TLS证书的方法。首先,TLS证书由证书颁发机构(CA)颁发,用于验证服务器身份和加密通信。接着,展示了如何使用`crypto/tls`包加载自签名证书启动HTTPS服务器。在生产环境中,通常使用CA签名的证书,这需要获取证书链和私钥。为了自动续期证书,可以利用Go的`acme/autocert`包与ACME服务交互。掌握这些技能对于确保Web服务的安全至关重要。
|
12天前
|
前端开发 应用服务中间件 网络安全
nginx配置SSL证书配置https访问网站 超详细(附加配置源码+图文配置教程)
nginx配置SSL证书配置https访问网站 超详细(附加配置源码+图文配置教程)
138 0
|
12天前
|
Ubuntu 应用服务中间件 Linux
nginx 配置代理ip访问https的域名配置
nginx 配置代理ip访问https的域名配置
101 2
|
12天前
|
应用服务中间件 网络安全 Apache
解决跨域和https不能访问的问题
【4月更文挑战第10天】解决跨域和https不能访问的问题
102 2
解决跨域和https不能访问的问题
|
12天前
|
安全 网络协议 网络安全
网络原理(5)--HTTPS是如何进行加密的
网络原理(5)--HTTPS是如何进行加密的
30 0
|
12天前
|
算法 Java 数据安全/隐私保护
java MD5 32位加密
java MD5 32位加密
23 0
|
12天前
|
Java 数据安全/隐私保护
Java实现最电话号码的简单加密源码
Java实现最电话号码的简单加密源码
22 0
|
12天前
|
存储 安全 算法
【接口加密】Java中的接口加密实践
【接口加密】Java中的接口加密实践