https信任证书的三种方

2024-09-06 12:08
文章标签 三种 https 证书 信任

本文主要是介绍https信任证书的三种方,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

苦逼的我调试AFNetworking发送https请求的bug ---------调试了一个上午,终于解决了


证书信任的过程:

证书的信任是通过代理的方式进行信任(NSURLConnection和NSURLSession两种方式进行信任)
客户端信任证书的过程:
1.当客户端要访问服务器的时候,服务器向客户端发送受保护的信任证书
2.客户端判断是否对客户端发送的证书进行信任,,
3.如果信任.则客户端会安装公钥在客户端,而服务器就拥有受保护证书的密钥,每一次向服务器请求数据的时候,服务器会先将要发送的数据进行密钥加密,客户端对所传数据通过公钥解密


下面分享一下自己的经验:

一开始请求数据先要信任证书,然后才能请求数据,不过对于百度,apple官网这样的大网站就不需要信任证书了,

只需要信任一次服务器证书

在信任证书的时候有两种方式:

大家熟知的有NSURLSession和NSURLConnection两种信任证书的方式,我会重点将第三种:

如果不信任证书的话会报下面的错误:

// NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9843)

一.NSURLSession的方式信任证书是通过代理的方式:

1.先懒加载全局的会话:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @property (nonatomicstrongNSURLSession *session;  
  2. - (NSURLSession *)session {  
  3.     if (_session == nil) {  
  4.         NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];  
  5.         _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];  
  6.     }  
  7.     return _session;  
  8. }  

2.发起数据任务

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // url  
  2.    NSURL *url = [NSURL URLWithString:@"https://域名"];  
  3.      
  4.    // 发起数据任务  
  5.    [[self.session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {  
  6.        NSLog(@"%@---%@",response,[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);  
  7.    }] resume];  

3.代理方法中实现证书的信任-----------

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task  
  2. didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge  
  3.  completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler {  
  4.     /* 
  5.      <NSURLProtectionSpace: 0x7fef2b686e20>:  
  6.      Host:mail.itcast.cn,  
  7.      Server:https,  
  8.      Auth-Scheme:NSURLAuthenticationMethodServerTrust, 
  9.      */  
  10.     // 判断是否是信任服务器证书  
  11.     if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {  
  1.  // 告诉服务器,客户端信任证书  
  2.         // 创建凭据对象  
  3.         NSURLCredential *credntial = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];  
  4.         // 通过completionHandler告诉服务器信任证书  
  5.         completionHandler(NSURLSessionAuthChallengeUseCredential,credntial);  
  6.     }  
  7.     NSLog(@"protectionSpace = %@",challenge.protectionSpace);  
  8. }  


二.NSURLConnection的方式信任证书也是通过代理的方式:

1.发送请求:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // url  
  2. NSURL *url = [NSURL URLWithString:@"https://mail.itcast.cn"];  
  3.   
  4. // request  
  5. NSURLRequest *request = [NSURLRequest requestWithURL:url];  
  6.   
  7. // 发送请求  
  8. [NSURLConnection connectionWithRequest:request delegate:self];  

2.信任证书
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #pragma mark - NSURLConnectionDataDelegate 代理方法  
  2. - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {  
  3.     // 判断是否是信任服务器证书  
  4.     if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {  
  5.         // 告诉服务器,客户端信任证书  
  6.         // 创建凭据对象  
  7.         NSURLCredential *credntial = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];  
  8.         // 告诉服务器信任证书  
  9.         [challenge.sender useCredential:credntial forAuthenticationChallenge:challenge];  
  10.     }  
  11. }  
3.获取请求到的数据
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {  
  2.     NSLog(@"data = %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);  
  3. }  

三.AFNetworking的方式信任服务器证书:

先上代码:
[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];  
  2. manager.securityPolicy.validatesDomainName = NO;  
  3. manager.responseSerializer = [AFHTTPResponseSerializer serializer];  
  4.   manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json"@"text/json"@"text/javascript",@"text/html", nil nil];  
  5. [manager GET:@"https://域名" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {  
  6.     NSLog(@"%@",downloadProgress);  
  7. } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {  
  8.     NSLog(@"%@---%@",[responseObject class],responseObject);  
  9.     NSLog(@"%@",[[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding]);  
  10. } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {  
  11.     NSLog(@"%@",error);  
  12. }];  


注意解释遇到的坑:
1.https的协议直接请求的时候会报下面的错:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9843)


2.设置属性
不能将 validatesDomainName设置为NO,当设置为NO以后可以发出任意的请求,所以要将其设置为YES(默认是YES)-----重点

manager.securityPolicy.validatesDomainName =YES;

AFNetworking 的安全相關設定放在 AFSecurityPolicy,它定義了三種 SSL Pinning Mode:

  • AFSSLPinningModeNone : 你不必將憑證跟你的 APP 一起打包,完全信任伺服器的憑證
  • AFSSLPinningModeCertificate : 比對伺服器憑證跟你的憑證是否完全匹配
  • AFSSLPinningModePublicKey : 只比對伺服器憑證的 public key 跟你的憑證的 public key 是否匹配

那要選用何種模式比較好呢?

AFSSLPinningModeCertificate 比較安全但也比較麻煩,它會比對你打包的憑證跟伺服器的憑證是否一致。因為你的憑證是跟 APP 一起打包的,這也就代表說如果你的憑證過期了或是變動了,你就得出一版新的 APP 而且舊版 APP 的憑證就失效了。你也可以在每次 APP 啟動時,就自動連到某個伺服器下載最新的憑證,不過此時這個下載連線就會是有風險的。

AFSSLPinningModePublicKey 則是只有比對憑證裡的 public key,所以即使伺服器憑證有所變動,只要 public key 不變,就能通過驗證。

所以如果你能確保每個使用者總是使用最新版本的 APP(例如是公司企業內部專用的),那就可以考慮 AFSSLPinningModeCertificate,否則的話選擇 AFSSLPinningModePublicKey 是比較實際的作法。


解决了证书信任的问题,也就是说设置上面的属性以后就可以信任证书了


但是问题没有解决:越到了经常遇到的问题,就是请求的数据打印有问题,

Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" 


原因:

这是因为 AFNetworking默认把响应结果当成json来处理,(默认manager.responseSerializer = [AFJSONResponseSerializer serializer]) ,很显然,我们请求的百度首页 返回的并不是一个json文本,而是一个html网页,但是AFNetworking并不知道,它坚信请求的结果就是一个json文本!然后固执地以json的形式去解析,显然没办法把一个网页解析成一个字典或者数组,所以产生了上述错误.

然而,我们期望它能够正确地处理这个情形,而不是提示一个错误. 
这时候 你必须告诉AFNetworking:别把这个网页当json来处理! 

解决办法:

只需要在发送请求前加入:manager.responseSerializer = [AFHTTPResponseSerializer serializer]


以上步骤就可以实现https证书的信任和正确的获取例如baidu.com首页的html的源码...


附加说明:

网页上加载的数据本质是字符串,我们将获取到的网页数据通过二进制转字符串的形式可以讲网页数据进行打印:

 NSLog(@"%@",[[NSStringalloc]initWithData:responseObjectencoding:NSUTF8StringEncoding]);






有了上面的解决办法是不是不知道如何获取凭证能,别急,下面添加如何获取制定域名的凭证:

参考链接:

http://nelson.logdown.com/posts/2015/04/29/how-to-properly-setup-afnetworking-security-connection/


这篇关于https信任证书的三种方的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1141964

相关文章

软考系统规划与管理师考试证书含金量高吗?

2024年软考系统规划与管理师考试报名时间节点: 报名时间:2024年上半年软考将于3月中旬陆续开始报名 考试时间:上半年5月25日到28日,下半年11月9日到12日 分数线:所有科目成绩均须达到45分以上(包括45分)方可通过考试 成绩查询:可在“中国计算机技术职业资格网”上查询软考成绩 出成绩时间:预计在11月左右 证书领取时间:一般在考试成绩公布后3~4个月,各地领取时间有所不同

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法   消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法 [转载]原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“

Jenkins 插件 地址证书报错问题解决思路

问题提示摘要: SunCertPathBuilderException: unable to find valid certification path to requested target...... 网上很多的解决方式是更新站点的地址,我这里修改了一个日本的地址(清华镜像也好),其实发现是解决不了上述的报错问题的,其实,最终拉去插件的时候,会提示证书的问题,几经周折找到了其中一遍博文

Android逆向(反调,脱壳,过ssl证书脚本)

文章目录 总结 基础Android基础工具 定位关键代码页面activity定位数据包参数定位堆栈追踪 编写反调脱壳好用的脚本过ssl证书校验抓包反调的脚本打印堆栈bilibili反调的脚本 总结 暑假做了两个月的Android逆向,记录一下自己学到的东西。对于app渗透有了一些思路。 这两个月主要做的是代码分析,对于分析完后的持久化等没有学习。主要是如何反编译源码,如何找到

3.比 HTTP 更安全的 HTTPS(工作原理理解、非对称加密理解、证书理解)

所谓的协议 协议只是一种规则,你不按规则来就无法和目标方进行你的工作 协议说白了只是人定的规则,任何人都可以定协议 我们不需要太了解细节,这些制定和完善协议的人去做的,我们只需要知道协议的一个大概 HTTPS 协议 1、概述 HTTPS(Hypertext Transfer Protocol Secure)是一种安全的超文本传输协议,主要用于在客户端和服务器之间安全地传输数据

HTTP协议 HTTPS协议 MQTT协议介绍

目录 一.HTTP协议 1. HTTP 协议介绍 基本介绍: 协议:  注意: 2. HTTP 协议的工作过程 基础术语: 客户端: 主动发起网络请求的一端 服务器: 被动接收网络请求的一端 请求: 客户端给服务器发送的数据 响应: 服务器给客户端返回的数据 HTTP 协议的重要特点: 一发一收,一问一答 注意: 网络编程中,除了一发一收之外,还有其它的模式 二.HTT

结构化开发方法的三种基本控制结构

结构化开发方法概述 什么是结构化开发方法? 结构化开发方法是一种程序设计和系统开发的理念,旨在通过使用清晰、可预测的控制结构来提高程序的可读性、可维护性和可靠性。该方法强调使用标准化的编程结构,以减少程序中的错误并提高代码的逻辑清晰度。 结构化编程的历史背景 结构化编程(Structured Programming)这一概念最早由计算机科学家艾兹赫尔·戴克斯特拉(Edsger W. Dij

Springboot工程配置https访问

背景 因为前端工程使用nginx配置了https访问,在https直接请求我们Springboot后端的http接口会报错。那么我们就需要配置使得我们后端的springboot服务支持https访问。 证书生成 在配置springboot工程https之前,我们需要生成自签名证书以及Spring Boot通常使用的PKCS#12格式的密钥库。 生成自签名证书 openssl req -x

企业网银登录提示请确认您已插入工商银行U盾证书的解决方法

昨天受人之托帮小企业财务解决上网银的问题 因为不是专业做这个的,所以只能安装“常识”行事,但结果实在是令人意想不到。 排错的步骤: 同一台电脑上尝试不同浏览器,发现360浏览器的接受度相当普遍;给U盾换不同的连接线;在不同的电脑上安装银行的插件,再重复上面的步骤1和步骤2;最终的结果,在一台电脑上可以走到下一步,但时好时坏,无法解决问题;到知乎上找答案,在一篇说明里有提到定制的qq浏览器,最后

2015多校联合训练第一场Assignment(hdu5289)三种解法

题目大意:给出一个数列,问其中存在多少连续子序列,子序列的最大值-最小值< k 这题有三种解法: 1:单调队列,时间复杂度O(n) 2:RMQ+二分,时间复杂度O(nlogn) 3:RMQ+贪心,时间复杂度O(nlogn) 一:RMQ+二分 RMQ维护最大值,最小值,枚举左端点i,二分找出最远的符合的右端点j,答案就是ans += j - i+1;(手推一下就知道) 比如1 2 3