iOS搞开发用什么笔记本 APP必须使用HTTPS怎么搞

iOS应用网络安全之HTTPS - 简书
iOS应用网络安全之HTTPS
移动互联网开发中iOS应用的网络安全问题往往被大部分开发者忽略,iOS9和OS X 10.11开始Apple也默认提高了安全配置和要求.本文以iOS平台App开发中对后台数据接口的安全通信进行解析和加固方法的分析.
HTTPS/SSL的基本原理
安全套接字层 (Secure Socket Layer, SSL) 是用来实现互联网安全通信的最普遍的标准。Web 应用程序使用 HTTPS(基于 SSL 的 HTTP),HTTPS 使用数字证书来确保在服务器和客户端之间进行安全、加密的通信。在 SSL 连接中,客户机和服务器在发送数据之前都要对数据进行加密,然后由接受方对其进行解密。
当浏览器(客户端)需要与某个安全站点建立连接时,先建立TCP连接(三次握手),然后再发生 SSL会话握手:
浏览器将通过网络发送请求安全会话的消息(通常请求以 https 而非 http 开头的 URL)。
服务器通过发送其证书(包括公钥)进行响应。
浏览器将检验服务器的证书是否有效,并检验该证书是否是由其证书位于浏览器的数据库中的(并且是可信的)CA 所签发的。它还将检验 CA 证书是否已过期。
如果证书有效,浏览器将生成一个==一次性的、唯一的==会话密钥,并使用服务器的公钥对该会话密钥进行加密。然后,浏览器将把加密的会话密钥发送给服务器,这样服务器和浏览器都有一份会话密钥。
服务器可以使用其专用密钥对消息进行解密,然后恢复会话密钥。
握手之后,即表示客户端已验证了 Web 站点的身份,并且只有该客户端和 Web 服务器拥有会话密钥副本。从现在开始,客户机和服务器便可以使用该会话密钥对彼此间的所有通信进行加密。这样就确保了客户机和服务器之间的通信的安全性。
上面是一般也是应用最普遍的单向验证方式,由浏览器(客户端)来验证服务端的合法性;其实也可以做双向验证,服务器也可以验证浏览器(客户端)的合法性,不过一般使用在银行业务上,比如U盾之类。我们现在关注普遍的单向验证方式的应用。
2. iOS移动开发HTTPS应用现状
当下绝大部份的移动互联网项目都采用HTTP、HTTPS协议作为前后端的数据接口协议。而iOS开发群体中,绝大部分都在项目中应用了第三方开源的HTTP请求框架AFNetworking来快速而高效的开发,毕竟快鱼吃慢鱼的时代嘛。AFNetworking请求HTTP接口简直是简单得不能再简单了。只不过从iOS9.0开始需要设置Info.plist中App Transport Security打开非HTTP的资源加载,因为Apple默认只允许采用经过权威证书颁发机构签名的证书的HTTPS站点的访问,一切是为了安全。安全。安全。 那么我们重点来分析采用HTTPS协议的后台接口的一般使用方式: HTTPS的服务器配置的证书分两大类,一类是经过权威机构签名颁发的证书,这样证书通常是要花钱买服务的,当然现在也有少数机构提供免费的证书签名服务。另一类就是服务器配置的是研发人员自己签名生成的证书。
3.AFN调用使用权威机构颁发证书的HTTPS接口
现在AFNetworking框架已经修复了上半年爆出的SSL中间人攻击漏洞,并强烈要求开发者使用公钥绑定或者证书绑定的安全策略,那么正确使用AFNetworking请求这类证书的HTTPS站点代码很简单如下:
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
policy.validatesDomainName = YES;
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.securityPolicy =
manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheD
对于这类证书的站点,Info.plist都不需要设置,因为已经是权威机构颁发的证书了,我们只需要设置验证绑定方式和验证域名以防止中间人攻击,毕竟申请证书是花了钱(现在也有免费的申请,比如WoSign),省事一点。
4.AFN调用使用我们自己签名证书的HTTPS接口
对于使用我们自己签名的证书来说,浏览器打开web站点也会默认阻止访问,除非用户手动把该站点加入信任列表,这个手动加入的过程其实就是不去验证服务器的合法性,任性的认为服务器是可信赖的。 那么手动加入信任列表,这样会导致证书的验证过程压根没发生,虽然可以成功访问目标服务器返回我们需要的数据,其实,这中间很有可能返回的数据不是正真的目标服务器返回的数据,也可能是网络传输中间的第三者伪装返回的数据。传输的数据被人窃取甚至纂改都是很可能的。
4.1 不正确的做法
浏览器手动加入自签名站点到信任列表这个操作的功能相当于iOS开发中AFNetworking的API的如下做法:
A 非权威机构颁发证书的HTTPS请求一样必须先在Info.plist设置如下:
&key&NSAppTransportSecurity&/key&
&key&NSAllowsArbitraryLoads&/key&
B AFNetworking代码设置SecurityPolicy
是我前面博客所讲的配置方法配置的自签名证书。
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//允许非权威机构颁发的证书
manager.securityPolicy.allowInvalidCertificates = YES;
//也不验证域名一致性
manager.securityPolicy.validatesDomainName = NO;
//关闭缓存避免干扰测试
manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheD
[manager GET:@"/channel/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id
_Nullable responseObject) {
NSLog(@"%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
经过如上两步设置之后,我们可以在iOS应用中访问我们采用自签名证书的HTTPS站点了。但是这个是不安全的,因为他在没有使用HTTPS/SSL代理和使用像Charles那样的HTTPS/SSL代理的情况下都可以访问服务器资源. 完全可以说是白费功夫,只能防止“君子”在网络中用Wireshark之类来TCP抓包嗅探。因为毕竟还是HTTPS加密了传输数据了。那为什么我要说这样是白费功夫呢,因为这个办法不能防止中间人攻击!比如用户可以给手机设置HTTPS的SSL代理(比如Charles),完全可以在代理中看到明文数据,所以,既然用了HTTPS就要防止中间人攻击,不然还不如不用HTTPS。
下面我们来看看怎么用Charles代理抓包工具所抓到的HTTPS传输的数据:
Charles代理抓包
上图是在Mac上运行Charles工具代理抓包,真机和Mac电脑同一个局域网,并设置代理为Mac机的IP和Charles的代理端口8888,然后启动App请求网络后抓到的数据。是不是很意外啊。HTTPS的数据也抓出明文了。显然这样是非常不安全的,那么当我们使用自签名证书的时候,我们该如何来在App端(客户端)严格的验证服务器的合法性呢?
4.2 正确的做法
我们要在App端严格验证服务器的合法性,防止网络中间的代理或者防火墙进行中间人的攻击和证书欺骗,那么我们需要把服务器配置的证书打包到客户端程序中(私钥留服务器不要分发不用泄露,非常重要),在代码里去读取该证书/公钥信息和服务器返回的进行匹配验证. 在iOS开发中,从Xcode7和iOS9开始,Apple提升了App的网络安全性,App默认只能进行对采用权威机构签名颁发证书的Web站点进行访问(信任的HTTPS),而自签名的证书的HTTPS站点也被列为属于例外,所以我们需要在App的Info.plist中单独为我们的域名设置Exception Domains"白名单",而不是打开Allow Arbitrary Loads全部放开,设置信息如下:
Xcode的Info.plist中NSAppTransportSecurity设置
&key&NSAppTransportSecurity&/key&
&key&NSExceptionDomains&/key&
&key&&/key&
&key&NSExceptionAllowsInsecureHTTPLoads&/key&
这样就不像上面那个方法那样一刀切全部放开, 而是单独为某个域名放开设置.当然上面也可以使用放开全部的设置NSAllowsArbitraryLoads为true.但是我建议使用白名单.
除此之外,要做到严格验证防止像Charles那样的中间人代理抓包,AFNetworking代码应该用如下设置:
//服务器端配置的包含公钥的证书分发到客户端后,需要转换为DER格式的证书文件.
//openssl x509 -outform der -in .crt -out .der
NSString *certFilePath = [[NSBundle mainBundle] pathForResource:@"" ofType:@"der"];
NSData *certData = [NSData dataWithContentsOfFile:certFilePath];
NSSet *certSet = [NSSet setWithObject:certData];
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey withPinnedCertificates:certSet];
policy.allowInvalidCertificates = YES;
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.securityPolicy =
//关闭缓存避免干扰测试
manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheD
[manager GET:@"/channel/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id
_Nullable responseObject) {
NSLog(@"%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
上面的代码能够验证服务器身份在没有使用代理的时候可以正常访问服务器的资源,但是一旦用户给手机网络设置使用了如Charle那样的HTTPS/SSL代理服务,则会出现服务器证书验证失败,SSL网络连接会断开,老板再也不用担心数据接口被人抓包或者代理给扒出来了.故达到防止中间人攻击的效果.
当使用Charles SSL代理时Xcode调试终端出错信息图:
Xcode调试终端出错信息
代理服务器Charles那边的出错信息图:
Charles那边的出错信息
最后,关于iOS9和OSX 10.11 开发时,Xcode的Info.plist的NSAppTransportSecurity详细设置方法请参考Apple官方文档:
更多iOS/Linux开发资料和视频资源请去:iOS开发之只能访问https不能访问http - 简书
iOS开发之只能访问https不能访问http
使用AFNetworking访问网络,发现网络访问失败。输出错误信息:The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
Google后查证,iOS9引入了新特性App Transport Security (ATS)。详情:新特性要求App内访问的网络必须使用HTTPS协议。但是现在公司的项目使用的是HTTP协议,使用私有加密方式保证数据安全。现在也不能马上改成HTTPS协议传输。最终找到以下解决办法:在Info.plist中添加NSAppTransportSecurity类型Dictionary。
在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean值设为YES
看到很多同学修改后还是不能用:在Filter中搜索Info.plist,选择Info.plist进行编辑
按照上面提到的方式添加信息,正确的修改会看到下图这个样子,注意类型NSAppTransportSecurity为Dictionary,NSAllowsArbitraryLoads为Boolean,复制粘贴的时候,不要多了空格,segment fault 页面上直接复制,经常会多一个出空格!
注意: 单元测试下面也有一个Info.plist,修改那个文件是没有作用的!
补充说明上面介绍的方法虽然解决了网络访问的问题,但是苹果提供的安全保障也被关闭了。不过,按照国内的现状,关闭这个限制也许是更实际的做法。至于原因就太多了,第三方SDK(几乎都是访问HTTP),合作伙伴接入(不能要求它们一定要支持HTTPS)。如果你的App没有受到这些原因的限制,还是更建议你增加HTTPS支持,而不是关闭限制。请大家根据项目的实际情况作调整。出于安全考虑我们提倡使用HTTPS,退而求其次,优先考虑使用例外:将允许访问的域加入到配置列表中,对于实在不支持HTTPS的,应该首先考虑添加例外。
添加例外的方式也很简单:左键Info.plist选择open with source code然后添加类似如下的配置:
&key&NSAppTransportSecurity&/key&
&key&NSExceptionDomains&/key&
&key&&/key&
&key&NSIncludesSubdomains&/key& &true/&
&key&.cn&/key&
&key&NSIncludesSubdomains&/key& &true/&
根据自己需要的域名修改, NSIncludeSubdomains 顾名思义是包括子域的意思。参考:
总结:苹果正在加大应用安全的管控,这个举措可以看出苹果对信息安全的重视,也暴露出大部分应用传输数据时都是未经过加密的,或使用私有方式加密,以至于苹果开始对开发者提出要求。私有加密虽然一定程度上是安全的,但是终究不是一个长久之计。全世界这么多安全专家在维护HTTPS安全,早日使用HTTPS确保信息安全才是王道!也省去了私有加密协议的安全隐患!
我就是我,移动开发爱好者!
github:/SuAdrenine
CSDN:http://blog.csdn.net/myincludeiOS开发 APP必须使用HTTPS怎么搞? - 知乎235被浏览20733分享邀请回答NSMutableArray *policies = [NSMutableArray array];
if (self.validatesDomainName) {
if (self.realDomain.length & 0)
[policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)self.realDomain)];
[policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)];
[policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()];
SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies);
3. 测试的时候,将ATS的开关打开,Allow Arbitrary Loads设为NO,并且保证手机系统是iOS9以上。服务端支持要求:服务器必须支持传输层安全(TLS)协议1.2以上版本;证书必须使用SHA256或更高的哈希算法签名;必须使用2048位以上RSA密钥或256位以上ECC算法等。如果想了解哪几种加密是被充许的,详见官方文档,另附,后台地址是否支持ATS的一个检测网站:只需访问 ,输入域名和端口进行检查(如下图所示),一键检测搞定,如:以上回答来自腾讯- tedyang 同学,Bugly已获得授权。596 条评论分享收藏感谢收起标签:至少1个,最多5个
苹果公司强制所有iOS App在日前使用HTTPS加密,这就意味着,如果您的APP如果仍采用HTTP传输,那么,在Apple Store中您的APP将不再能被用户下载使用。
HTTPS的基础原理和通信过程
HTTPS(Secure Hypertext Transfer Protocol) 安全超文本传输协议 它是一个安全通信通道,它基于 HTTP 开发,用于在客户计算机和服务器之间交换信息。它使用安全套接字层(SSL)进行信息交换,简单来说它是 HTTP 的安全版,是使用 TLS/SSL 加密的 HTTP 协议。
HTTP 协议采用明文传输信息,存在信息窃听、信息篡改和信息劫持的风险,而协议 TLS/SSL 具有身份验证、信息加密和完整性校验的功能,可以避免此类问题。
TLS/SSL 全称安全传输层协议 Transport Layer Security, 是介于 TCP 和 HTTP 之间的一层安全协议,不影响原有的 TCP 协议和 HTTP 协议,所以使用 HTTPS 基本上不需要对 HTTP 页面进行太多的改造。
如何对自己的服务器进行HTTPS切换,详情请看原文:
Http域名替换为Https方法
使用PHP的preg_replace方法对未加S域名进行替换:
// 替换规则
$pattern_arr = array(
"/http\:\/\/alibaba\.com/i",
"/http\:\/\/baidu\.com/i"
// 需要替换的内容
$replacement_arr = array(
// 需要替换的字符串或数组
$str = array(
"我们都是中国人哈",
"腾讯公司域名",
// $str = "我们都是中国人哈";
// 该方法支持字符串或数组传递
$ret = preg_replace($pattern_arr, $replacement_arr, $str);
dump($ret);
0 收藏&&|&&0
你可能感兴趣的文章
3 收藏,2.4k
分享到微博?
你好!看起来你挺喜欢这个内容,但是你还没有注册帐号。 当你创建了帐号,我们能准确地追踪你关注的问题,在有新答案或内容的时候收到网页和邮件通知。还能直接向作者咨询更多细节。如果上面的内容有帮助,记得点赞 (????)? 表示感谢。
明天提醒我
我要该,理由是:}

我要回帖

更多关于 软件开发搞笑图 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信