https的证书认证 iOS版
一、证书链
SecTrustRef:
SecTrustRef trust = challenge.protectionSpace.serverTrust;
需要先拿出一个 SecTrustRef 对象,它是一种执行信任链验证的抽象实体,包含着验证策略(SecPolicyRef)以及一系列受信任的锚点证书,而我们能做的也是修改这两样东西而已。
SecTrustResultType trustResult = kSecTrustResultInvalid;
// 函数的内部递归地从叶节点证书到根证书的验证
OSStatus statue = SecTrustEvaluate(trust, &trustResult);
二、系统验证策略及修改:
SecTrustSetPolicies
域名验证
可以通过以下的代码获得当前的验证策略:
CFArrayRef policiesRef;
SecTrustCopyPolicies(trust, &policiesRef);
打印 policiesRef 后,你会发现默认的验证策略就包含了域名验证,即“服务器证书上的域名和请求域名是否匹配”。如果你的一个证书需要用来连接不同域名的主机,或者你直接用 IP 地址去连接,那么你可以重设验证策略以忽略域名验证:
三、系统本地证书链的修改与维护
下面是设置锚点证书的做法:
1 NSMutableArray *certificates = [NSMutableArray array];
2
3 NSDate *cerData = /* 在 App Bundle 中你用来做锚点的证书数据,证书是 CER 编码的,常见扩展名有:cer, crt...*/
4
5 SecCertificateRef cerRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)cerData);
6
7 [certificates addObject:(__bridge_transfer id)cerRef];
8
9 // 设置锚点证书。
SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)certificates);
只调用 SecTrustSetAnchorCertificates () 这个函数的话,那么就只有作为参数被传入的证书作为锚点证书,连系统本身信任的 CA 证书不能作为锚点验证证书链。要想恢复系统中 CA 证书作为锚点的功能,还要再调用下面这个函数:
1 // true false CA SecTrustSetAnchorCertificatesOnly(trust, );
这样,再调用 serverTrustIsVaild() 验证证书有效性就能成功了。
四、AFNetwork对app内嵌证书的支持:
会自动扫描bundle中.cer的文件,并引入
解决方法:AFNetworking是允许内嵌证书的,通过内嵌证书,AFNetworking就通过比对服务器端证书、内嵌的证书、站点域名是否一致来验证连接的服务器是否正确。由于CA证书验证是通过站点域名进行验证的,如果你的服务器后端有绑定的域名,这是最方便的。将你的服务器端证书,如果是pem格式的,用下面的命令转成cer格式
openssl x509 -in <你的服务器证书>.pem -outform der -out server.cer
然后将生成的server.cer文件,如果有自建ca,再加上ca的cer格式证书,引入到app的bundle里,AFNetworking在
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModeCertificate];
或者
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModePublicKey];
情况下,会自动扫描bundle中.cer的文件,并引入,这样就可以通过自签证书来验证服务器唯一性了。
五、AFNetwork的证书验证模式
AFSecurityPolicy分三种验证模式:
AFSSLPinningModeNone
这个模式表示不做SSL pinning,
只跟浏览器一样在系统的信任机构列表里验证服务端返回的证书。若证书是信任机构签发的就会通过,若是自己服务器生成的证书就不会通过。
AFSSLPinningModeCertificate
这个模式表示用证书绑定方式验证证书,需要客户端保存有服务端的证书拷贝,这里验证分两步,第一步验证证书的域名有效期等信息,第二步是对比服务端返回的证书跟客户端返回的是否一致。
AFSSLPinningModePublicKey
这个模式同样是用证书绑定方式验证,客户端要有服务端的证书拷贝,
只是验证时只验证证书里的公钥,不验证证书的有效期等信息。只要公钥是正确的,就能保证通信不会被窃听,因为中间人没有私钥,无法解开通过公钥加密的数据。
六、整体验证过程:
所以在 iOS 中,证书是否有效的标准是:
信任链中如果只含有有效证书并且以可信锚点(trusted anchor)结尾,那么这个证书就被认为是有效的。
其中可信锚点指的是系统隐式信任的证书,通常是包括在系统中的 CA 根证书。不过你也可以在验证证书链时,设置自定义的证书作为可信的锚点。
具体到使用 NSURLSession 走 HTTPS 访问网站,-URLSession:didReceiveChallenge:completionHandler: 回调中会收到一个 challenge,也就是质询,需要你提供认证信息才能完成连接。这时候可以通过 challenge.protectionSpace.authenticationMethod 取得保护空间要求我们认证的方式,如果这个值是 NSURLAuthenticationMethodServerTrust 的话,我们就可以插手 TLS 握手中“验证数字证书有效性”这一步。
如果我们要实现这个代理方法的话,需要提供 NSURLSessionAuthChallengeDisposition(处置方式)和 NSURLCredential(资格认证)这两个参数给 completionHandler 这个 block:
七、系统默认实现
系统的默认实现(也即代理不实现这个方法)是验证这个信任链,结果是有效的话则根据 serverTrust 创建 credential 用于同服务端确立 SSL 连接。否则会得到 “The certificate for this server is invalid...” 这样的错误而无法访问。
八、双向认证:
NSURLCredential
NSURLCredential代表的是一个身份验证证书。URL Loading系统支持3种类型的证书:password-based user credentials, certificate-based user credentials, and certificate-based server credentials。
参考文献:
https://www.cnblogs.com/oc-bowen/p/5896041.html
https的证书认证 iOS版的更多相关文章
- java实现https免证书认证
		
java实现https免证书认证 解决方法: 1.下载两个包,httpclient-4.2.jar和httpcore-4.2.jar,复制以下代码就可使用. 2.调用类代码: String htt ...
 - RestTemplate请求https忽略证书认证
		
RestTemplate是Spring提供的用于访问Rest服务的客户端,提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率.RestTemplate 默认使用J2SE提供的方式( ...
 - https绕过证书认证请求 Get或Post请求(证书过期,忽略证书)
		
报错信息 解决: postman方式 java请求 报错信息 javax.net.ssl.SSLHandshakeException: sun.security.validator.Validator ...
 - svnkit https 忽略证书认证
		
直接上代码 解决jdk版本问题:Security.setProperty("jdk.tls.disabledAlgorithms", ""); import j ...
 - https 单向双向认证说明_数字证书, 数字签名, SSL(TLS) , SASL_转
		
转自:https 单向双向认证说明_数字证书, 数字签名, SSL(TLS) , SASL 因为项目中要用到TLS + SASL 来做安全认证层. 所以看了一些网上的资料, 这里做一个总结. 1. 首 ...
 - 转:  https 单向双向认证说明_数字证书, 数字签名, SSL(TLS) , SASL
		
转自: http://www.cnblogs.com/mailingfeng/archive/2012/07/18/2597392.html 因为项目中要用到TLS + SASL 来做安全认证层. 所 ...
 - QT https post请求(QNetworkRequest要设置SSL证书,而SSL证书认证有三种,实测成功)
		
以VS开发为例.因为https访问需要用到SSL认证,而QT默认是不支持SSL认证,所以在使用之前必须先做一些准备工作: 需要安装OpenSSL库: 1.首先打开http://slproweb.com ...
 - 用OpenSSL生成自签名证书在IIS上搭建Https站点(用于iOS的https访问)
		
前提: 先安装openssl,安装有两种方式,第一种直接下载安装包,装上就可运行:第二种可以自己下载源码,自己编译.这里推荐第一种. 安装包:http://slproweb.com/products/ ...
 - Https握手协议以及证书认证
		
1. 什么是https Https = http + 加密 + 认证 https是对http的安全强化,在http的基础上引入了加密和认证过程.通过加密和认证构建一条安全的传输通道.所以https可以 ...
 
随机推荐
- [android] 开启新的activity获取他的返回值
			
应用场景:打开一个新的activity,在这个activity上获取数据,返回给打开它的界面 短信发送时,可以直接选择系统联系人 界面布局是一个线性布局,里面右侧选择联系人在EditText的右上,因 ...
 - 22.QT-QXmlStreamReader解析,QXmlStreamWriter写入
			
XML介绍 XML 用于存储数据,数据的形式类似于树结构(参考: http://www.runoob.com/xml/) 示例如下 <?xml version="1.0" e ...
 - nginx代理配置 配置中的静态资源配置,root 和 alias的区别。启动注意事项
			
这篇主要内容是:nginx代理配置 配置中的静态资源配置,root 和 alias的区别.启动注意事项! 为什么会在window上配置了nginx呢?最近我们的项目是静态资源单独放在一个工程里面,后端 ...
 - (10)Microsoft office  Word 2013版本操作入门_word表格
			
1.套用word模板 :点击[文件]---[新建]---选择合适模板创建即可. word中插入[书法字帖]: 2.插入表格 :点击[插入]---[表格]输入行和列 ,固定列宽为“自动”时 默认沾满左 ...
 - Docker 系列三(容器管理).
			
一.运行容器 1.基于镜像新建一个容器并启动 : tomcat:8.0 -i:交互式操作 -t:终端 -rm:容器退出后随之将其删除,可以避免浪费空间 -p :端口映射 -d :容器在后台运行 指明了 ...
 - IIS服务器被配置为不列出此目录的内容
			
使用 IIS 管理器启用目录浏览. 打开 IIS 管理器. 在“功能”视图中,双击“目录浏览”. 在“目录浏览”页上,在“操作”窗格中单击“启用”.
 - Tomcat post参数长处理
			
如下图所示:增加maxPostSize="-1"属性即可
 - 解决ui-router路由监听$stateChangeStart、$stateChangeSuccess、$stateChangeError不执行的问题
			
问题解答 angular1项目导入ui-router之后,使用路由监听,代码如下 angular.module('app', ['ui.router', 'ui.router.state.events ...
 - 9.Odoo产品分析 (二) – 商业板块(4) –讨论(1)
			
查看Odoo产品分析系列--目录 讨论模块就是一个信息记录和消息提醒的功能,在登录到odoo平台的时候第一个界面就是它: 1. 收件箱 收件箱,登录者的邮箱管理,并显示未读邮件数量: 点击上面 ...
 - 远程连接MySQL数据库问题总结
			
远程连接MySQL数据库时,陆陆续续遇到了一些杂七杂八的问题,相信很多人也曾经遇到过这类问题,下面总结归纳在下面,方便以后直接查找. 1:出现ERROR 2003 (HY000): Can't con ...