转:http://www.jianshu.com/p/f312a84a944c

https封面

在WWDC 2016开发者大会上,苹果宣布了一个最后期限:到2017年1月1日 App Store中的所有应用都必须启用 App Transport Security安全功能。也就是说,自2017年起,网络请求必须由http改成https。正因为这个原因,我也打算尝试下适配Https网络请求。由于先前没有配置服务器经验,网上说的也很不详细,因此踩了不少坑,足足花了一天的时间。现在我把我配置的流程写下来,希望后来人能少走点弯路。(网上教程有,但是写得很乱,难理解,这里我打算用最通俗的语言来描述。)

概念误区:HTTPS和语言无关


一开始,我以为https应该像处理http报头一样,要写什么PHP代码(服务器语言是PHP),把客户端传来的证书经过处理验证什么的,然后再返回处理结果(类似于Token验证)。因此,一开始我就搜PHP怎么处理HTTPS请求,结果都是介绍怎么用PHP发送HTTPS请求的。经过一段时间纠结,我才意识到HTTPS的处理并不需要PHP做什么,你的服务器(比如apache)就已经帮你做好验证了,你只需要像接收http请求一样处理数据就可以了,也就是说,服务器增加HTTPS并不需要在代码中做什么,只要服务器配置下就好

关于HTTPS握手流程我觉得还是应该了解下,可以参考这份资料:https握手流程

简单得说就是客户端向服务器发起需求
,服务器把证书发给客户端,客户端验证下证书是否合法,然后用证书的数据加密传输数据给服务器,服务器解密

生成证书文件


看了上面的原理就知道,要HTTPS传输首先得有证书。在生成证书这方面我也遇到了很大的坑,几乎所有的网站都要生成2个证书,server.pemclient.pem。一开始我把server.pem配置到服务器上,把client.pem给AFNetwoking,结果怎么都通过不了验证!后来我发现只要AFNetworing使用server.pem验证就可以了,也就是说只要一份证书就行了。。。(真的不知道为什么要2份证书,如有大神欢迎指出)。

下面我将命令行代码贴出来,主要参考这篇文章:参考文章

//第一步,为服务器端和客户端准备公钥、私钥
# 生成服务器端私钥
openssl genrsa -out server.key 1024
# 生成服务器端公钥
openssl rsa -in server.key -pubout -out server.pem //第二步,生成 CA 证书
# 生成 CA 私钥
openssl genrsa -out ca.key 1024
# X.509 Certificate Signing Request (CSR) Management.
openssl req -new -key ca.key -out ca.csr
# X.509 Certificate Data Management.
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt

在第二步时会出来一个填写资料的界面(我已经填好大家可以参考,有些地方可以空着)

Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Zhejiang
Locality Name (eg, city) []:Hangzhou
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My CA
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:localhost
Email Address []:

这里有点要注意, Common Name (e.g. server FQDN or YOUR name) []: 这一项,是最后可以访问的域名,我这里为了方便测试,写成 localhost ,如果是为了给网站生成证书,需要写成 xxxx.com 。

//第三步,生成服务器端证书
# 服务器端需要向 CA 机构申请签名证书,在申请签名证书之前依然是创建自己的 CSR 文件
openssl req -new -key server.key -out server.csr
# 向自己的 CA 机构申请证书,签名过程需要 CA 的证书和私钥参与,最终颁发一个带有 CA 签名的证书
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.cr

同样会有信息填写,照旧写就好了。

第四步,生成cer文件
使用openssl 进行转换
openssl x509 -in server.crt -out server.cer -outform der

如果完成,就会得到这么多文件

证书文件

配置服务器


为了方便,我是以mac本地电脑做服务器,使用的是XAMPP搭建的服务器使用的是apache。在其他服务器上应该就是文件路径位置不一样,其他应该是一样的。如果有些服务器没开启ssl,可以网上搜索怎么开启。

修改httpd-ssl.conf文件 把server.crt和server.key的路径修改对就好了
SSLCertificateFile /apache/conf/server.crt
SSLCertificateKeyFile /apache/conf/server.key

由于我的服务器默认开启ssl,因此我就修改下证书路径就好了。
我们来浏览器访问下

浏览器访问https

按我标出的框来访问证书,就可以看见我们刚才自己填的数据

服务器返回的证书

因为不同服务器配置不同,不能一概而论,所以大家还是根据自己服务器的情况再配置。

配置AFNetworking


这里直接上代码

+ (AFSecurityPolicy*)customSecurityPolicy
{
// /先导入证书
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"cer"];//证书的路径
NSData *certData = [NSData dataWithContentsOfFile:cerPath]; // AFSSLPinningModeCertificate 使用证书验证模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; // allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
// 如果是需要验证自建证书,需要设置为YES
securityPolicy.allowInvalidCertificates = YES; //validatesDomainName 是否需要验证域名,默认为YES;
//假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
//置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
//如置为NO,建议自己添加对应域名的校验逻辑。
securityPolicy.validatesDomainName = NO; securityPolicy.pinnedCertificates = @[certData]; return securityPolicy;
} + (void)post:(NSString *)url params:(NSDictionary *)params success:(void (^)(id))success failure:(void (^)(NSError *))failure
{
// 1.获得请求管理者
AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
// 2.申明返回的结果是text/html类型
mgr.responseSerializer = [AFHTTPResponseSerializer serializer]; // 加上这行代码,https ssl 验证。
[mgr setSecurityPolicy:[NetworkHelpManager customSecurityPolicy]]; // 3.发送POST请求
[mgr POST:url parameters:params
success:^(NSURLSessionDataTask *operation, id responseObj) {
if (success) {
success(responseObj);
}
} failure:^(NSURLSessionDataTask *operation, NSError *error) {
if (failure) {
failure(error);
}
}];
}

还要记得把证书添加到项目中来哦

项目中的证书

下面要介绍下证书的验证模式 AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

  • AFSSLPinningModeNone

不做任何验证,只要服务器返回了证书就通过

  • AFSSLPinningModePublicKey

只验证公钥部分,只要公钥部分一致就验证通过,如图所示,红色框起来的部分只要一致就通过

客户端和服务器端证书对比
  • AFSSLPinningModeCertificate

除了公钥外,其他能容也要一致才能通过验证。

配置结果


下面我们用Charles抓包看看是否成功加密了。

抓包结果

返回的数据依稀能看出我们证书里的内容,但是数据已经加密了。

总结


配置https其实并不难,既然迟早要更新还不如早一点配置好。其实很多时候都是我们不愿意做,而不是不能做。多一点耐心,多一点实践,就能多一点突破。

我是翻滚的牛宝宝,欢迎大家评论交流~

ios开发笔记

© 著作权归作者所有
举报文章
关注o翻滚的牛宝宝o

写了 27902 字,被 289 人关注,获得了 315 个喜欢

最美之物,永不凋零

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

赞赏支持

IOS Https适配摸索的更多相关文章

  1. ios https适配(单向验证)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https是http+tls.是在http和tcp之间添加了一层ssl加密验证,ssl将http发送的信息在将要发到传输层时进行了加密,同样数据从 ...

  2. iOS 10 适配 ATS(app支持https通过App Store审核)

    iOS 10 适配 ATS 一. HTTPS 其实HTTPS从最终的数据解析的角度,与HTTP没有任何的区别,HTTPS就是将HTTP协议数据包放到SSL/TSL层加密后,在TCP/IP层组成IP数据 ...

  3. iOS 9 适配需要注意的问题

    iOS 9 适配需要注意的问题 1`网络适配_改用更安全的HTTPS iOS9把所有的http请求都改为https了:iOS9系统发送的网络请求将统一使用TLS 1.2 SSL.采用TLS 1.2 协 ...

  4. iOS 9 适配中出现的坑

    整理 iOS 9 适配中出现的坑(图文) 2015-10-22 iOS开发 库克表示:“现在在中国有150多万的开发者在iOS当中开发应用程序,我们鼓励更多的人开发应用程序,也鼓励更多的创业加入.” ...

  5. iOS屏幕适配

    ## iOS屏幕适配 ### iOS屏幕适配发展史 1> iPhone4以前(没有iPad) * 不需要屏幕适配 2> iPad.iPhone5等设备出现 * 需要做横竖屏适配 * aut ...

  6. 【转】iOS屏幕适配

    一.iOS屏幕适配发展历程 设备 适配技术 4及以前(iPad未出) 直接用代码计算 有了iPad autoResizing 有不同屏幕的iPhone后 autoLayout 有更多不同屏幕的iPho ...

  7. iOS:界面适配--iPhone不同机型适配 6/6plus

    iOS:界面适配--iPhone不同机型适配 6/6plus        机型变化 坐标:表示屏幕物理尺寸大小,坐标变大了,表示机器屏幕尺寸变大了: 像素:表示屏幕图片的大小,跟坐标之间有个对应关系 ...

  8. iOS 9 适配,我咋还没遇到这么多坑呢呀

    iOS 9 适配,我咋还没遇到这么多坑呢呀 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 ...

  9. IOS 10适配https 包含对于一些http的一些兼容配置

    iOS10 从2017年1月1日起苹果提出所有新提交的App默认不允许使用NSAllowsArbitraryLoads来绕过ATS的限制,也就是说强制我们用HTTPS,如果不这样的话提交App可能会被 ...

随机推荐

  1. mysql 时间类型精确到毫秒、微秒及其处理

    一.MySQL 获得毫秒.微秒及对毫秒.微秒的处理 MySQL 较新的版本中(MySQL 6.0.5),也还没有产生微秒的函数,now() 只能精确到秒. MySQL 中也没有存储带有毫秒.微秒的日期 ...

  2. foxmail同步QQ邮箱里的所有文件夹

    随着微信消息的轰炸,我决定重拾邮箱.为了方便管理邮箱,我下载并试用了Foxmail和网易邮箱大师,Foxmail不确定用什么语言开发的,可能是C++或者Delphi(早期应该是Delphi,最新的版本 ...

  3. Go语言之高级篇beego框架之cookie与session

    1.cookie的用法 this.Ctx.SetCookie("name", name, maxage, "/") this.Ctx.SetCookie(&qu ...

  4. 用 Prettier 统一团队的代码风格~

    使用 prettier 自動調整 JavaScript 樣式 GFM 格式说明 为什么你不能缺少Linter(以及代码美化工具) 使用 prettier 自動調整 JavaScript 樣式 Reac ...

  5. Redis在SSM项目中的简单使用

    一.基于SSM的Redis环境配置 前提是你的开发电脑安装和配置好了redis,如果没安装请看Window配置Redis环境和简单使用 1.1.pom文件中引入redis客户端jar包(pom.xml ...

  6. RPC简述

    在某种意义上,WebService.REST均是RPC的实现,那么RPC的发展过程如何呢?本文参考了wikipedia,对RPC做一下简要摘记. RPC(RemoteProcedureCall),是进 ...

  7. Shell获取某目录下所有文件夹的名称

    查看目录下面的所有文件: #!/bin/bash cd /目标目录 for file in $(ls *) do echo $file done 延伸的方法,查看目录下面的所有目录 #!/bin/ba ...

  8. java.awt.headless 模式

    1. 什么是 java.awt.headless? Headless模式是系统的一种配置模式.在系统可能缺少显示设备.键盘或鼠标这些外设的情况下可以使用该模式. 2. 何时使用和headless mo ...

  9. M1 卡技术规范

    射频卡简单来讲就是卡的一种工作方式,通过感应的方式来工作,也能够把全部的感应卡都统称为射频卡. IC卡的范围比較广.芯片外露的接触式IC卡.芯片内置的感应式IC卡和双界面IC卡都可统称为IC卡.IC卡 ...

  10. ROS nodelet的使用

    ROS是一种基于分布式网络通讯的操作系统,整个机器人控制系统是由一个Master主节点和若干个功能相对独立的Node子节点组成,这也是ROS系统最主要的特点就是分布式以及模块化的设计.在ROS通讯过程 ...