AFNetworking3.0 Https P12证书
最近服务器由原来的ice中间件改为https。方便了和服务器交互时不用自己aes加密了。
-之前服务器人员和我(IOS)都没有使用过https,所以https跑不通很难说是服务器没有配置好还是IOS这边网络没有写好。
-开始服务器提供了两个证书(自签名)。 一个.cer一个p12.
导入AFNetworking 之后按照其他资料提供的方法很简单。
NSString *urlString = @"https://xxxxx网址";
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"https" ofType:@"cer"]; //获取cer证书
NSData * certData =[NSData dataWithContentsOfFile:cerPath];
NSSet * certSet = [[NSSet alloc] initWithObjects:certData, nil];
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; //采用证书验证模式
// 是否允许,NO-- 不允许无效的证书 YES-- 允许无效的证书(因为用的是自签名证书这里设置为YES,没有经过CA认证)
[securityPolicy setAllowInvalidCertificates:YES];
// 设置证书
[securityPolicy setPinnedCertificates:certSet];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.securityPolicy = securityPolicy;
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// request 这里开始GET请求
[manager GET:urlString parameters:nil progress:^(NSProgress * progress){
} success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"OK === %@",array); //请求成功
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"error ==%@",error.description); //请求失败
}];
-经过我一番研究,太TM简单了啊添加几个参数就行了。
-谁知道按照这样怎么也跑不通。调试了半天,都跑到afnetworking源码里面去查了,好像查出来证书验证通过不了。AFSecurityPolicy.h这个文件里面的 AFServerTrustIsValid方法就是通过不了,里面有个枚举值
代表证书验证的结果
typedef uint32_t SecTrustResultType;
enum {
kSecTrustResultInvalid = 0,
kSecTrustResultProceed = 1,
kSecTrustResultConfirm SEC_DEPRECATED_ATTRIBUTE = 2,
kSecTrustResultDeny = 3,
kSecTrustResultUnspecified = 4,
kSecTrustResultRecoverableTrustFailure = 5,
kSecTrustResultFatalTrustFailure = 6,
kSecTrustResultOtherError = 7
};
具体枚举值什么意思直接百度就能搜出来。验证结果一直是kSecTrustResultRecoverableTrustFailure,5.意思就是证书验证失败。
-开始怀疑服务器给的.cer证书有问题。
-查了几天资料,找到一个只用p12证书的资料。(因为搜索资料时好多人说了证书的问题,所以怀疑和cer证书转换的格式或者编码有关,所以决定用原始的p12证书)
-结果用原始的p12证书和原生的网络跑通了。用afnetworking的话资料都是用了cer,加上cer证书就跑不通。本来决定用原生网络,后来又要封装各种post啊什么的太麻烦了,所以去研究afnetworking和p12证书了。
-最后解决。
-afnetworking的AFURLSessionManager.m类里面的方法
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{ }
afnetworking源码里面这个方法只有一行代码,把它替换成
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
NSString *method = challenge.protectionSpace.authenticationMethod;
NSLog(@">>>>1 %@", method); if([method isEqualToString:NSURLAuthenticationMethodServerTrust]){ NSString *host = challenge.protectionSpace.host;
NSLog(@">>>>2 %@", host); NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
return;
} else if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate]) { NSString *thePath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"];
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
CFDataRef inPKCS12Data = (CFDataRef)CFBridgingRetain(PKCS12Data);
SecIdentityRef identity; // 读取p12证书中的内容
OSStatus result = [self extractP12Data:inPKCS12Data toIdentity:&identity]; if(result != errSecSuccess){
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
return;
} SecCertificateRef certificate = NULL;
SecIdentityCopyCertificate(identity, &certificate); const void *certs[] = {certificate};
CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, , NULL); NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(NSArray*)CFBridgingRelease(certArray) persistence:NSURLCredentialPersistencePermanent]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
}
}
这个是收到验证证书时候的回调。
再在这个类里面添加一个方法
-(OSStatus) extractP12Data:(CFDataRef)inP12Data toIdentity:(SecIdentityRef*)identity {
OSStatus securityError = errSecSuccess;
CFStringRef password = CFSTR("yaoguang123");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
securityError = SecPKCS12Import(inP12Data, options, &items);
if (securityError == 0) {
CFDictionaryRef ident = (CFDictionaryRef)CFArrayGetValueAtIndex(items,0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue(ident, kSecImportItemIdentity);
*identity = (SecIdentityRef)tempIdentity;
}
if (options) {
CFRelease(options);
}
// NSLog(@">>>>>>>> inP12Data = %@", inP12Data);
// NSLog(@">>>>>>>> identity = %@", identity);
return securityError;
}
之后想要获取数据,不用设置验证模式啊什么的,直接调用
- (void)testHttps { manager = [AFHTTPSessionManager manager]; [manager GET:@"https://www.iyaoguang.com:8443/App/login?phone=123&password=123" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"???????????? %@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"?????????? %@",error);
}]; }
成功!
AFNetworking3.0 Https P12证书的更多相关文章
- iOS 适配https(AFNetworking3.0为例)
众所周知,苹果有言,从2017年开始,将屏蔽http的资源,强推https楼主正好近日将http转为https,给还没动手的朋友分享一二 1.准备证书 首先找后台要一个证书(SSL证书,一般你跟后台说 ...
- OpenSSL 1.0.0生成p12、jks、crt等格式证书的命令个过程(转)
OpenSSL 1.0.0生成p12.jks.crt等格式证书的命令个过程 此生成的证书可用于浏览器.java.tomcat.c++等.在此备忘! 1.创建根证私钥命令:openssl g ...
- OpenSSL 1.0.0生成p12、jks、crt等格式证书的命令个过程 -参考自http://lavasoft.blog.51cto.com/62575/1104993/
OpenSSL 1.0.0生成p12.jks.crt等格式证书的命令个过程 此生成的证书可用于浏览器.java.tomcat.c++等.在此备忘! 1.创建根证私钥命令:openssl g ...
- OpenSSL 1.0.0生成p12、jks、crt等格式证书的命令个过程
OpenSSL 1.0.0生成p12.jks.crt等格式证书的命令个过程 此生成的证书可用于浏览器.java.tomcat.c++等.在此备忘! 1.创建根证私钥命令:openssl g ...
- iOS开发--基于AFNetWorking3.0的图片缓存分析
图片在APP中占有重要的角色,对图片做好缓存是重要的一项工作.[TOC] 理论 不喜欢理论的可以直接跳到下面的Demo实践部分 缓存介绍 缓存按照保存位置可以分为两类:内存缓存.硬盘缓存(FMDB.C ...
- iOS_SN_基于AFNetworking3.0网络封装
转发文章,原地址:http://www.henishuo.com/base-on-afnetworking3-0-wrapper/?utm_source=tuicool&utm_medium= ...
- java获取https网站证书,附带调用https:webservice接口
一.java 获取https网站证书: 1.创建一个java工程,新建InstallCert类,将以下代码复制进去 package com; import java.io.BufferedReader ...
- iOS- 利用AFNetworking3.0+(最新AFN) - 实现文件断点下载
官方建议AFN的使用方法 0.导入框架准备工作 •1. 将AFNetworking3.0+框架程序拖拽进项目 •2. 或使用Cocopod 导入AFNetworking3.0+ •3. ...
- [转贴]使用CryptoAPI解析X509证书和P12证书
原文在 http://bbs.pediy.com/archive/index.php?t-97663.html,但是觉得这篇文章非常好,我抄下来作我笔记用 一.解析X509证书 1.从磁盘上的证书文件 ...
随机推荐
- linux 内核学习之五 system_call过程分析
一 使用gdb工具跟踪分析一个自添加的系统调用 应用程序的进程通常在用户空间下运行,当它调用一个系统调用时,进程进入内核空间,执行的是kernel内部的代码,从而具有执行特权指令的权限,完成特定的 ...
- Oracle存储过程动态创建临时表/存储过程执行权限问题--AUTHID CURRENT_USER
关于Oracle存储过程执行权限问题的解决 http://blog.sina.com.cn/s/blog_6ceed3280101hvlo.html (2014-04-02 04:06:28) 转载▼ ...
- hudson slave搭建
Hudson Slave搭建 使用Hudson搭建分布式的构建环境非常方便,客户端也不需要太多的操作,只要能执行java命令就行. hudson默认采用master方式进行安装,master作为 ...
- Ubuntu下用wireshark抓取802.11封包并进行过滤分析
要用wireshark抓802.11的包 需要在linux下进行. 要在linux下抓802.11的包 需要在linux下安装无线网卡驱动. 所以 在正式抓取之前先把这两样东西搞起来. *没有特殊说明 ...
- Dotspatial 创建面状图层
using DotSpatial.Controls;using DotSpatial.Data;using DotSpatial.Data.Forms;using DotSpatial.Plugins ...
- VMware虚拟机无法ping通/分配虚拟IP/远程访问的问题的解决方案:
最近老板要写俩web系统,没有自己的服务器,没办法,只好先借用下学院的服务器做下测试调试.那好,问题来了~ 学院的服务器不是我一个人在维护,经常有其他人登进登出(!!!担心文件丢失啊!!!),硬伤!! ...
- Python开发入门与实战14-基于Extjs的界面
14. 基于Extjs的界面 上一章我们实现了一个原生的html例子,本章我们将采用Extjs实现界面的展现,来说明MVC模式下我们是怎么考虑界面与业务层的关系的. 14.1. 引用Extjs目录 首 ...
- Diwali
转帖 今天是印度新年(Diwali), 全公司庆祝,午饭不要钱 一.不到美国不知道,三人行必有我师,二人行必有老印.. 一大早“春眠不觉晓,处处闻老印”:晚上遛个弯“举头望明月,低头见老印”:到山 ...
- js中快速获取数组中的最大值最小值
var a=[1,2,3,5]; alert(Math.max.apply(null, a));//最大值 alert(Math.min.apply(null, a)); //最小值 多维数组如下 v ...
- JavaScript数组模拟栈和队列
*栈和队列:js中没有真正的栈和队列的类型 一切都是用数组对象模拟的 栈:只能从一端进出的数组,另一端封闭 FILO 何时使用:今后只要仅希望数组只能从一端进 ...