前提 :
1.当前iOS 官方文档没有明确检验是否安装描述文件的直接使用方法,都是间接检测(以安装mdm的描述文件为例,官方文档好像提到了通过每隔一段时间轮询设备 /或者尝试发送mdm推送查看服务器 查看是否有反馈 来检测某个设备是否安装描述文件),
参考链接 :
https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/MobileDeviceManagementProtocolRef/6-MDM_Best_Practices/MDM_Best_Practices.html#//apple_ref/doc/uid/TP40017387-CH5-SW2
2.如果当前设备安装的描述文件中,必须包含一个自签名的证书(即非苹果内嵌的信任的CA机构颁发的CA证书,无法直接在苹果系统直接就通过认证,),我们可以自己做一个签名文件,一起放到描述文件中,辅助我们完成这个功能
iOS 中HTTPS的携带的证书是否信任检测机制
1.安装iOS系统的时候 ,iOS系统中会包含很多知名的的CA机构颁发的CA根证书,不同的iOS版本 包含的机构不同,具体查看下面的链接
参考链接 :https://support.apple.com/zh-cn/HT204132
- 当客户端或者iOS系统去访问一个https的服务器(以Server替代)时,Server会返回一个数字证书,数字证书包含当前Server的公钥,当前证书的签发机构(包含签发机构的信任链),当前证书的有效期,序列号等等信息
3.当客户端收到服务器给的返回的证书(此处只讨论信任链模块的检测,先不讨论具体的通信的校验),去校验证书的有效性,分为两种情形:
A : 当前证书的信任链的根证书 在当前系统的可信任列表中
服务器会根据证书中包含的信息(有效期等待)简单判断是否在有效期,如果在有效期,在查看证书的信任链,找到该证书的上级颁发机构,如果找到,再去找当前颁发机构的上级机构,一直往上找,直到找到该CA机构颁发的根证书(自己给自己签名的证书),如果该根证书的CA颁发机构在当前系统的颁发机构的信任列表中(即上面提到那个系统植入的所有的信任机构),然后根据根证书的公钥,再一级一级的将下级信任链上的公钥一一解密,(通过上级签发机构的公钥解密下级机构的公钥),直到解密到当前证书的公钥,查看与当前证书的公钥是否一致,如果一致,可以信任. 否则,不可以信任,如果是浏览器,会提示有证书不可信等等警示信息(不同于自签名的提示),如果是app,应该会主动中断链接,网络报errcode -999,被取消.
B : 当前证书的信任链的根证书 不在当前系统的可信任列表中
服务器会根据证书中包含的信息(有效期等待)简单判断是否在有效期,如果在有效期,在查看证书的信任链,找到该证书的上级颁发机构,如果找到,再去找当前颁发机构的上级机构,一直往上找,直到找到该CA机构颁发的根证书(自己给自己签名的证书),如果该根证书的CA颁发机构在当前系统的颁发机构的信任列表中(即上面提到那个系统植入的所有的信任机构),如果该根证书不在系统的信任列表中(自签名类型),如果是浏览器,浏览器会给出提醒,如果是我们自己开发的app,就会进入证书挑战(在<NSURLSessionTaskDelegate>和<NSURLSessionDelegate>这两个代理中,didReceiveChallenge这个方法中,前者比后者的方法多了一个task,系统会优先调用后者,后者没有实现,会去调用前者),我们可以在这个方法中处理当前证书的校验(以AFNetworking的代码为例):
注意绿色框 框出的方法,是处理域名校验的处理
域名校验的部分代码
我们需要在这里面处理我们的挑战,根据我们的策略,一般都是在我们bundle里面嵌入证书,处理是否和我们自签名的一致,如果直接就返回可以信任的话,会有风险,这就是好多自签名的服务器,一般客户端bundle中会包含这个证书,专门处理这个挑战,
ps:其实客户端处理这个挑战,信任的时候 就是将这个证书临时加入了系统信任的根证书里面,到时候我们的正式校验就通了,就相当于走了A情形了.
关于描述文件是否安装的检验逻辑
当客户端安装描述文件的时候,描述文件会获取用户的授权,描述文件中如果包含自签名的证书,如果用户同意了安装并且安装,该自签名的正式理论上也是被系统信任的了,所以系统的信任列表中会包含该证书,一旦用户卸载了描述文件,该系统中的信任列表中,该自签名的证书的也会被移除,基于这个机制,我们可以通过判断该证书是否被系统信任,来判断当前是否按照描述文件,下面是校验代码,通过bundle中的描述文件,来判断当前设备是否受系统信任
客户端读取证书信息(可以是多个证书),生成证校验对象,并且设置信任策略,根据
证书当前的OSStatus的值来判断是否受系统信任,注意区别上面的域名信任的时候的那个设置方法,方便理解.
iOS11之前,这样判断就可以
iOS 11就需要这样了,对于信任的枚举值类型 增加了一个 (但是这个不太靠谱,正在评估)
2017.09.20更新
到此.描述文件是否本地安装的校验机制就走完了,这是我的理解,有错误请指出,共同学习,谢谢