iOS升级HTTPS通过ATS你所要知道的

2023-10-22 19:10
文章标签 https ios ats 升级 知道 所要

本文主要是介绍iOS升级HTTPS通过ATS你所要知道的,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

由于苹果规定2017年1月1日以后,所有APP都要使用HTTPS进行网络请求,否则无法上架,因此研究了一下在iOS中使用HTTPS请求的实现。网上搜索了一些比较有用资料,大家可以参考下

苹果强制升级的HTTPS不仅仅是在接口HTTP上加个S那么简单:
它所有满足的是iOS9中新增App Transport Security(简称ATS)特性:
那满足ATS我们需要做什么呢
1.必须是苹果信任的CA证书机构颁发的证书
2.后台传输协议必须满足: TLS1.2 (这很重要, 后面的自制证书满足这个条件是前提)
3.签字算法只能是下面的一种:

TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

4.证书必须使用SHA256或者更好的哈希算法进行签名,要么是2048位或者更长的RSA密钥,要么就是256位或更长的ECC密钥。

目前有两种升级到HTTPS得方法:
1.第三方认证的颁发CA证书(推荐)
2.自己制作证书(这种不知道能不能满足苹果的审核)

一: 第三方认证的颁发CA证书

证书到底长什么样子呢? 取个栗子:
大家请打开https://www.baidu.com
然后看到


百度的证书分析


那些证书机构颁发的证书能用:苹果官方信任证书

收费SSL证书: 网上百度一大把, 收费还挺贵的,自己可以多找几个对比一下
免费SSL证书: 除了收费的CA证书机构, 你还可以去腾讯云申请免费的SSL证书, 教程免费在腾讯云申请SSL证书的方法
沃通(WoSign)免费的SSL证书最近被苹果封杀了, 能不能用大家可以看一下苹果的公告: 您的苹果手机轻点“设置”>“通用”>“关于本机”>"证书信任设置">"进一步了解被信任的证书"去了解

检测你的接口是否满足苹果的ATS要求, 有以下两种方法:

1.腾讯云提供的检测页面检测


腾讯云的检测页面


2 终端输入 nsurl --ats-diagnostics --verbose 你的接口地址
大家可以参考这篇文章,里面的说的很明白:
关于iOS9中的App Transport Security相关说明及适配(更新于2016.7.1)
里面会详细说明你的证书哪点不符合ATS要求
当然下面自己制作证书去实现HTTPS的,检测不通过的,所以我觉得审核会被拒
这种方法配置好了, 在手机端就什么都不用配置就可以请求了

二: 自己制作证书

苹果官方信任证书里说到有三种证书:

1 可信的根证书用于建立信任链,以验证由可信的根签署的其他证书,例如,与 Web 服务器建立安全连接。当 IT 管理员创建 iPhone、iPad 或 iPod touch 
的配置描述文件时,无需提供这些可信的根证书。
2 始终询问的证书不受信任,但不受阻止。使用其中一个证书时,系统将提示您选择是否信任该证书。
3 已阻止的证书视为被盗用,将不再受信任。

自制证书我觉得应该就是属于第二种情况, 所以这种方法我也不知道能不能通过苹果的审核, 只是提供一个方法给大家参考, 看到网上有人说可以,有人说不可以, 不到1月1号,自己没试过都不敢说大话
这种方式拿到后台的接口用谷歌浏览器打开跟百度的证书是有区别的


自己制作证书


很明显没有绿锁, 当打开的时候会询问是否连接这个不受信任的连接才会进一步打开, 下面就来一步步的实现(包括怎么制作证书)
iOS使用自签名证书实现HTTPS请求
iOS Https协议 自签证书访问数据参考这个例子的时候,博主自带的Demo AFN框架请求不了数据, 我用了最新AFN版本的成功返回数据
还可以参考一下
iOS 10 适配 ATS app支持https通过App Store审核

我在利用原生的代码测试时遇到的问题

@interface ViewController () <NSURLSessionDelegate>@end@implementation ViewController- (void)viewDidLoad {}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] 
delegate:self delegateQueue:[NSOperationQueue mainQueue]];NSURLSessionDataTask *task =  [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] 
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);}];[task resume];
}- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)responsecompletionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {NSLog(@"接收到服务器响应");//注意:这里需要使用completionHandler回调告诉系统应该如何处理服务器返回的数据//默认是取消/**NSURLSessionResponseCancel = 0,            默认的处理方式,取消NSURLSessionResponseAllow = 1,             接收服务器返回的数据NSURLSessionResponseBecomeDownload = 2,    变成一个下载请求NSURLSessionResponseBecomeStream           变成一个流*/completionHandler(NSURLSessionResponseAllow);
}- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTaskdidReceiveData:(NSData *)data {NSLog(@"获取到服务段数据");NSLog(@"%@",[self jsonToDictionary:data]);
}- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error {NSLog(@"请求完成%@", error);
}- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challengecompletionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))
completionHandler {NSLog(@"证书认证");if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust]) {do{SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];NSCAssert(serverTrust != nil, @"serverTrust is nil");if(nil == serverTrust)break; /* failed *//***  导入多张CA证书(Certification Authority,支持SSL证书以及自签名的CA),请替换掉你的证书名称*/NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"cer"];//自签名证书NSData* caCert = [NSData dataWithContentsOfFile:cerPath];NSCAssert(caCert != nil, @"caCert is nil");if(nil == caCert)break; /* failed */SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCert);NSCAssert(caRef != nil, @"caRef is nil");if(nil == caRef)break; /* failed *///可以添加多张证书NSArray *caArray = @[(__bridge id)(caRef)];NSCAssert(caArray != nil, @"caArray is nil");if(nil == caArray)break; /* failed *///将读取的证书设置为服务端帧数的根证书OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);NSCAssert(errSecSuccess == status, @"SecTrustSetAnchorCertificates failed");if(!(errSecSuccess == status))break; /* failed */SecTrustResultType result = -1;//通过本地导入的证书来验证服务器的证书是否可信status = SecTrustEvaluate(serverTrust, &result);if(!(errSecSuccess == status))break; /* failed */NSLog(@"stutas:%d",(int)status);NSLog(@"Result: %d", result);BOOL allowConnect = (result == kSecTrustResultUnspecified) || (result == kSecTrustResultProceed);if (allowConnect) {NSLog(@"success");}else {NSLog(@"error");}/* kSecTrustResultUnspecified and kSecTrustResultProceed are success */if(! allowConnect){break; /* failed */}#if 0/* Treat kSecTrustResultConfirm and kSecTrustResultRecoverableTrustFailure as success *//*   since the user will likely tap-through to see the dancing bunnies */if(result == kSecTrustResultDeny || result == kSecTrustResultFatalTrustFailure || result == kSecTrustResultOtherError)break; /* failed to trust cert (good in this case) */
#endif// The only good exit pointNSLog(@"信任该证书");NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];completionHandler(NSURLSessionAuthChallengeUseCredential,credential);return [[challenge sender] useCredential: credentialforAuthenticationChallenge: challenge];}while(0);}// Bad dogNSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,credential);return [[challenge sender] cancelAuthenticationChallenge: challenge];
}- (NSDictionary *)jsonToDictionary:(NSData *)jsonData {NSError *jsonError;NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves 
error:&jsonError];return resultDic;
}@end

下面说说我在配置自己制作证书过程中遇到的问题:
1.转换证书: 把后台给你的.crt证书转化为.cer后缀
终端命令行openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der

2.利用系统的方法来不到- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler { NSLog(@"证书认证");}这个方法的时候, 是因为后台的传输协议还没升级到TLS1.2, 叫后台升级后就可以来到验证证书的这个方法了.

3.拖入证书读取不出证书数据
参考: https的证书错误,错误码-1012问题及解决方案

SDWebImage: 项目中大家用到AFN请求网络数据, 升级验证SSL证书的方案相信你看完上面的参考文章已经没问题了, 我给出的代码, 自定义网络请求也没问题了, 还有就是SDWebImage框架的请求HTTPS的图片时,大家可以绕过证书验证去加载图片[imageView sd_setImageWithURL:[NSURL URLWithString:urlString] placeholderImage:self.placeholder options:SDWebImageAllowInvalidSSLCertificates];

恩, 这就是这几天升级HTTPS觉得有帮助的参考和总结.希望帮到你



文/床前明月_光(简书作者)
原文链接:http://www.jianshu.com/p/2d72ef8dbf5a
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

这篇关于iOS升级HTTPS通过ATS你所要知道的的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转

Ubuntu如何升级Python版本

《Ubuntu如何升级Python版本》Ubuntu22.04Docker中,安装Python3.11后,使用update-alternatives设置为默认版本,最后用python3-V验证... 目China编程录问题描述前提环境解决方法总结问题描述Ubuntu22.04系统自带python3.10,想升级

解决升级JDK报错:module java.base does not“opens java.lang.reflect“to unnamed module问题

《解决升级JDK报错:modulejava.basedoesnot“opensjava.lang.reflect“tounnamedmodule问题》SpringBoot启动错误源于Jav... 目录问题描述原因分析解决方案总结问题描述启动sprintboot时报以下错误原因分析编程异js常是由Ja

Linux升级或者切换python版本实现方式

《Linux升级或者切换python版本实现方式》本文介绍在Ubuntu/Debian系统升级Python至3.11或更高版本的方法,通过查看版本列表并选择新版本进行全局修改,需注意自动与手动模式的选... 目录升级系统python版本 (适用于全局修改)对于Ubuntu/Debian系统安装后,验证Pyt

MySQL 升级到8.4版本的完整流程及操作方法

《MySQL升级到8.4版本的完整流程及操作方法》本文详细说明了MySQL升级至8.4的完整流程,涵盖升级前准备(备份、兼容性检查)、支持路径(原地、逻辑导出、复制)、关键变更(空间索引、保留关键字... 目录一、升级前准备 (3.1 Before You Begin)二、升级路径 (3.2 Upgrade

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、

Nginx进行平滑升级的实战指南(不中断服务版本更新)

《Nginx进行平滑升级的实战指南(不中断服务版本更新)》Nginx的平滑升级(也称为热升级)是一种在不停止服务的情况下更新Nginx版本或添加模块的方法,这种升级方式确保了服务的高可用性,避免了因升... 目录一.下载并编译新版Nginx1.下载解压2.编译二.替换可执行文件,并平滑升级1.替换可执行文件

升级至三频BE12000! 华硕ROG魔盒Pro路由器首发拆解评测

《升级至三频BE12000!华硕ROG魔盒Pro路由器首发拆解评测》华硕前两天推出新一代电竞无线路由器——ROG魔盒Pro(StrixGR7Pro),该产品在无线规格、硬件配置及功能设计上实现全... 作为路由器行业的T1梯队厂商,华硕近期发布了新旗舰华硕ROG魔盒Pro,除了保留DIY属性以外,高达120

Python包管理工具pip的升级指南

《Python包管理工具pip的升级指南》本文全面探讨Python包管理工具pip的升级策略,从基础升级方法到高级技巧,涵盖不同操作系统环境下的最佳实践,我们将深入分析pip的工作原理,介绍多种升级方... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Python中你不知道的gzip高级用法分享

《Python中你不知道的gzip高级用法分享》在当今大数据时代,数据存储和传输成本已成为每个开发者必须考虑的问题,Python内置的gzip模块提供了一种简单高效的解决方案,下面小编就来和大家详细讲... 目录前言:为什么数据压缩如此重要1. gzip 模块基础介绍2. 基本压缩与解压缩操作2.1 压缩文