HTTPS 安全
在 iOS
应用程序中,使用 HTTPS
进行通信是一种更为安全的做法,也是官方所推荐的做法。但是即使使用了 HTTPS
,也有可能因为没有校验服务器证书的原因导致被中间人劫持。如果交互请求数据处理不当,攻击者可以解密得到明文通信数据;甚至进一步伪造App
的请求,这是极大的安全隐患。
这个检测方法也非常简单,就是打开 APP
登录帐号,使用抓包工具如Charles
去看是否有请求获取敏感信息,比如获取资源包或者文件脚本。
安全加固实施建议:
App
内要对HTTPS
证书做校验。- 避免使用有漏洞的第三网网络库(如
AFNetworking < 2.5.3
版本)。 - 关键数据(如登录密码、卡号、交易密码等)单独加密。
通讯协议安全
除了上面提到的明文传输密码的问题外,移动端应用还要面对黑客对于通讯协议的破解的威胁。在成功破解了通讯协议后,黑客可以模拟客户端登录,进而伪造一些用户行为,可能对用户数据造成危害。例如网络上游戏代练服务,有可能是该游戏的通讯协议被破解,黑客制作出了代练的机器人程序。
通讯协议被破解除了对于移动端游戏有严重危害外,对于应用也有很大的危害。例如针对微信,黑客可以制作一些僵尸帐号,通过向微信公共帐号后台发送垃圾广告,达到赢利目的。而 iPhone
设备上的 iMessage
通讯协议据说也被破解了,所以很多 iPhone
用户会收到来自 iMessage
的垃圾广告。
对于以上提到的问题,开发者可以选择类似protobuf
(Google
提供的一个开源数据交换格式,其最大的特点是基于二进制,因此比传统的 JSON 格式要短小得多) 之类的二进制通讯协议或者自己实现通讯协议,对于传输的内容进行一定程度的加密,以增加黑客破解协议的难度。
防止网络请求被抓包
App
安全越来越受重视,要分析一个App
,抓包是必不可少的,那么如何防止像Charles
之类(中间人攻击类型)的抓包软件的抓包呢?主要有以下几个思路:
- 检测是否使用了代理,检测到使用了代理就关闭网络请求。
- 使用自签名证书的应用和双向验证的应用。
- 通过
HTTP/1.1
及以上版本的CONNECT
请求方式 - 对返回的数据进行加密(
RSA | token | AES128
等等)
代理检测
当进行网络请求的时候,客户端判断当前是否设置了代理,如果设置了代理,不允许进行访问数据,以下为代理检测代码示例
代码语言:javascript复制 (BOOL)getProxyStatus {
NSDictionary *proxySettings = NSMakeCollectable([(NSDictionary *)CFNetworkCopySystemProxySettings() autorelease]);
NSArray *proxies = NSMakeCollectable([(NSArray *)CFNetworkCopyProxiesForURL((CFURLRef)[NSURL URLWithString:@"http://www.google.com"], (CFDictionaryRef)proxySettings) autorelease]);
NSDictionary *settings = [proxies objectAtIndex:0];
NSLog(@"host=%@", [settings objectForKey:(NSString *)kCFProxyHostNameKey]);
NSLog(@"port=%@", [settings objectForKey:(NSString *)kCFProxyPortNumberKey]);
NSLog(@"type=%@", [settings objectForKey:(NSString *)kCFProxyTypeKey]);
if ([[settings objectForKey:(NSString *)kCFProxyTypeKey] isEqualToString:@"kCFProxyTypeNone"]) {
//没有设置代理
return NO;
} else {
//设置代理了
return YES;
}
}
绕过代理发送请求
现在iOS
上的网络请求基本分为三类,
NSURLConnection
NSURLSession
CFNetWork
NSURLConnection
NSURLConnection
是 2003 年 iOS 2.0
随着第一版 Safari
的发布而发布的,它不单单是一个网络请求类,而是指代Foundation
框架的 URL
系统中的一系列关联的组件: NSURLRequest、NSURLResponse、NSURLProtocol、NSHTTPCookieStorage、NSURLCredentialStorage
以及同名类 NSURLConnection
。
NSURLSession
2013 年的 WWDC
大会上,iOS 7.0
推出了 NSURLSession
,对 Foundation URL
加载系统进行了彻底的重构,提供了更丰富的 API
来处理网络请求,如:支持 http2.0
协议、直接把数据下载到磁盘、同一 session
发送多个请求、下载时多线程异步处理和提供全局的 session
并可以统一配置等等,提高了 NSURLSession
的易用性、灵活性,更加地适合移动开发的需求。
CFNetWork
CFNetWork
是苹果提供的位于 Core Foundation
中的一个基于C
的底层框架,是对更底层OS
层BSD
socket
的封装,著名的网络框架ASI
网络请求方面就是对CFNetWork
进行封装的
绕过代理请求设置
如果在初始化 NSURLSession
的时候将 connectionProxyDictionary
属性设置为空。
configuration.connectionProxyDictionary = @{};
那么,当手机开启了代理服务(如:Charles
)的时候,用这个session
发起的网络请求并不会去走这个代理,而且默认的不走代理直接发起网络请求。
通过 HTTP/1.1 及以上版本的 CONNECT 请求方式
什么是CONNECT
请求?
平时工作中,GET
跟 POST
是我们用的比较多的请求方式,而CONNECT
是在 HTTP/1.1
协议中,HTTP/1.0
定义了三种请求方法: GET, POST
和 HEAD
方法,HTTP/1.1
新增了五种请求方法:OPTIONS、 PUT、DELETE、 TRACE 和 CONNECT
方法。
它主要是把服务器作为跳板,先验证用户名和密码等信息,再让服务器代替用户去访问其它网页,之后把数据返回给用户,之所以说采用CONNECT
请求当跳板,可以防止Charles
抓包,是因为 Charles
抓CONNECT
的请求,会识别为unknown
,所以就能达到防抓包的目的了。
对返回的数据进行加密(RSA | token | AES128 等等)
这种方式严格的不是说让Charles
抓不到包,而是让抓到的包别人看不懂,采用密文传输。