iOS开发避免安全隐患的要点总结

现在很多iOS的APP没有做任何的安全防范措施,导致存在很多安全隐患和事故,今天我们来聊聊iOS开发人员平时怎么做才更安全。

一、网络方面

用抓包工具可以抓取手机通信接口的数据。以Charles为例,用Charles可以获取http的所有明文数据,配置好它的证书后就可以模拟中间人攻击,获取https加密前的明文数据。

1.1 中间人攻击

先简要地说下什么是中间人攻击:

①客户端:“我是客户端,给我你的公钥” -> 服务端(被中间人截获)。

所以现在是:

客户端->中间人

②然后中间人把消息转给服务端,也就是:

中间人->服务端

③服务端把带有公钥的信息发送给客户端,但是被中间截获。所以是:

服务端-[服务端的公钥] ->中间人

④中间人把服务端的公钥替换成自己的公钥,发送给客户端,声称是服务端的公钥:

中间人-[中间人的公钥] ->客户端

⑤客户端用得到的公钥加密,实际是用中间人的公钥进行加密,所以中间人可以用自己的私钥解密,获取原始数据,然后再用服务端的公钥对原始数据(或者修改原始数据内容)加密后发送给服务端。

这样中间人就可以获取到双方的通信数据,并可以制造虚假数据。

1.2 如何防范中间人攻击?

下面开始说如何防范:

1.2.1 SSL Pinning

SSL Pinning的原理就是把服务端的公钥存到客户端中,客户端会校验服务端返回的证书是否和客户端保存的一致,这样就避免了中间人替换证书进行的攻击。

SSL Pinning的实现比较简单,只需要把CA证书放入项目中,通过Security framework实现NSURLSession上的SSL Pinning。如果用的是AFNetworking,代码更简单一点:

这样通过Charles抓包就会报错。

证书验证有可以只验证公钥(AFSSLPinningModePublicKey),也可以完全验证证书(AFSSLPinningModeCertificate)。

但是用SSL Pinning有个很严重的问题,就是如果证书有问题,只有发布新版本才能解决。如果新版本一直审核不通过,app的网络通信就全部挂掉了。

比如赛门铁克(Symantec)证书被google和iOS12不信任的问题。如果app内置了证书,就必须要重新发版。

1.2.2 接口内容进行加密

很多的app接口只对请求的参数进行加密和各种验证,而接口返回过来的数据就是明文。如果不用SSL Pinning来防止中间人攻击,也可以把接口返回的数据也进行加密,这样抓包工具抓到包后也依然不能破解。

比如微信,微信中的接口用的是http协议,但是内容全部进行了加密。

现在常用的是对称加密,加密效率比较快。如果app里有的数据特别重要,还是要用非对称加密,非对称加密更安全,但是效率会比较慢。

二、日志 2.1 Swift日志

Swift中打印日志的语法可以用print,也可以用NSLog。但是尽量别用NSLog,因为Swift中用NSLog,系统日志中是能查到的。可以通过pp助手、iTools或者Xcode的Devices and Simulators 来查看系统日志。

用print打印日志就不会出现在系统日志中。

2.2 OC日志

在release环境下不要输出NSLog日志。一般大家都会用宏定义解决,如下:

三、信息的存储 3.1 密钥

大部分的程序员喜欢直接把密钥放到宏或者常量里。

如:#define AES_KEY @“aaa123"

这样做很容易就可以被反编译出来。安全性比较差。可以用以下方法加强安全,增加破解的难度。

对密钥(A)进行加密后定义为宏(B),使用的时候进行解密得到密钥(A)。其中对密钥A加密的密钥为C。

因为在宏定义的时候我们如果定义成字符串,会直接存在data段,这样破解者很容易获取到。比较安全的做法是把C和B定义成uint8_t[]数组,这样每个字符就会放到text段的每个单独指令中。指令执行后生成字符串。这样就会很安全。

用一段长文本,按规则提取出里面的密钥,密钥是随机的。

在服务端和客户端定义一段长文本,app端随机生成起始位置和长度,把起始位置和长度进行移位等操作,生成相应的数字,对数字进行Base64编码,生成的字符串 传给服务端,服务端根据这个字符串 就能 解析出相关的密钥。

代码如下:

这样只是增加了破解者获取密钥的难度,其实并不能完全阻止破解者获取。

3.2 Keychain

越狱的iPhone可以查看导出Keychain保存的信息。Keychains的内容存放在sqlite中,目录为:/private/var/Keychains。可以通过keychain-dump可以查看钥匙串里存放的的内容。

所以保存到Keychain的数据一定要是加密之后的数据。

3.3 plist、sqlite

plist、sqlite可以直接在ipa安装文件中获取到,所以不要在这些文件中存放重要信息,如果要保存,就进行加密后再存放。

四、app加固 4.1 代码混淆

代码混淆就是把易读的类名、方法名替换成不易读的名字。常用的方法有宏替换和脚本替换。

比如本来方法名为:- (void)loadNetData; 进行代码混淆后,用class-dump导出头文件后会显示成修改后的方法名:- (void)showxhevaluatess;

4.2 用C语言

核心代码用C语言写,但是C语言的函数也可以被hook,比如用fishhook。开发人员可以用静态内联函数来防止hock,破解者就只能去理解代码的逻辑。

4.3 检测tweak

可以检测 /Library/MobileSubstrate/DynamicLibraries 下的 plist 文件里是否包含自己app的bundle id。如果包含,可以进行限制app的功能、提示该手机不安全 等。

(0)

相关推荐

  • 详解Nginx服务器和iOS的HTTPS安全通信

    详解Nginx服务器和iOS的HTTPS安全通信 简介 在网络通信中,使用抓包软件可以对网络请求进行分析,并进行重放攻击,重放攻击的解决方案一般是使用一个变化的参数,例如RSA加密的时间戳,但考虑到网络传输时延,时间戳需要有一定的误差容限,这样仍然不能从根本上防止重放攻击.想要较好的解决重放攻击问题,应考虑使用HTTPS通信,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输.身份认证的网络协议,比HTTP协议安全. 实现 对于用浏览器访问的网站,需要向CA申请证书才能保证HTTPS的网

  • 浅析iOS应用开发中线程间的通信与线程安全问题

    线程间的通信   简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信   线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务   线程间通信常用方法 复制代码 代码如下: - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; - (void)performSelecto

  • iOS开发中多线程的安全隐患总结

    资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题 一.解决方案 解决方案:使用线程同步技术(同步,就是协同步调,按预定的先后次序进行) 常见的线程同步技术是:加锁 1.OSSpinLock OSSpinLock叫做"自旋锁",等待锁的线程会处于忙等(busy-wait)状态,一直占用着CPU资源 目前已经不再安全,可能会出现优先级反转问题 如果等待

  • iOS安全防护系列之重签名防护与sysctl反调试详解

    一 重签名防护 想自己的app不被重签名,可以在代码中检测签名信息,然后采取措施. 1.查看证明组织单位 或者进入.app的包内容,查看embedded.mobileprovision信息security cms -D -i embedded.mobileprovision 找到<key>application-identifier</key>的value的第一部分就是 2.利用签名信息进行重签名防护 void checkCodesign(NSString *id){ // 描述文

  • iOS中多网络请求的线程安全详解

    前言 在iOS 网络编程有一种常见的场景是:我们需要并行处理二个请求并且在都成功后才能进行下一步处理.下面是部分常见的处理方式,但是在使用过程中也很容易出错: DispatchGroup:通过 GCD 机制将多个请求放到一个组内,然后通过 DispatchGroup.wait() 和 DispatchGroup.notify() 进行成功后的处理. OperationQueue:为每一个请求实例化一个 Operation 对象,然后将这些对象添加到 OperationQueue ,并且根据它们之

  • 探究iOS多线程究竟不安全在哪里?

    前言 共享状态,多线程共同访问某个对象的property,在iOS编程里是很普遍的使用场景,我们就从Property的多线程安全说起. Property 当我们讨论property多线程安全的时候,很多人都知道给property加上atomic attribute之后,可以一定程度的保障多线程安全,类似: @property (atomic, strong) NSString* userName; 事情并没有看上去这么简单,要分析property在多线程场景下的表现,需要先对property的类

  • iOS安全防护系列之ptrace反调试与汇编调用系统方法详解

    关于系统调用 ptrace是一个系统调用.那系统调用是什么东东呢?它是一个系统提供的很强大的底层服务.用户层的框架是构建在system call之上的. macOS Sierra大约提供了500个系统调用.通过以下命令来了解你系统上的系统调用的个数: ➜ ~ sudo dtrace -ln 'syscall:::entry' | wc -l 这个命令使用了另外一个更强大的工具叫DTrace,暂不详谈它. 一 lldb调试原理:debugserver 1.xcode的lldb之所以能调试app,是

  • iOS安全防护系列之字符串及系统函数隐藏详解

    前言 用hopper打开macho文件可以看出你具体函数跳转与字符串的使用,那么在项目中,你的加密Key就容易泄漏,你使用的加密方法如果是系统的,那么可以被fishhook给hook住,所以字符串和系统方法的隐藏可以作为安全防护的一环. 一 字符串加密 如果你使用对称加密,你的秘钥很可能被macho文件暴露 要想字符串不进常量区,可以先用一个字符去异或,然后再异或回来,字符串直接换算,就不会被macho暴露. //测试环境 static NSString * KEY(){ unsigned ch

  • iOS开发避免安全隐患的要点总结

    现在很多iOS的APP没有做任何的安全防范措施,导致存在很多安全隐患和事故,今天我们来聊聊iOS开发人员平时怎么做才更安全. 一.网络方面 用抓包工具可以抓取手机通信接口的数据.以Charles为例,用Charles可以获取http的所有明文数据,配置好它的证书后就可以模拟中间人攻击,获取https加密前的明文数据. 1.1 中间人攻击 先简要地说下什么是中间人攻击: ①客户端:"我是客户端,给我你的公钥" -> 服务端(被中间人截获). 所以现在是: 客户端->中间人 ②

  • IOS开发仿微信右侧弹出视图实现

    IOS开发仿微信右侧弹出视图实现 微信首页的+号,点击之后会弹出一个更多的视图,这个视图如何实现呢? 实现该效果可能需要以下技术要点: 1.图片拉伸,通过拉伸图片的中间的较小区域来保持图片的边上的形状 2.仿射变换,用到仿射变换的缩放,平移和合并,视图动画 3.navigationBar的样式设置 实现效果,如下: 本Demo图片来源微信安装包解压得到的图片 实现代码: // // ViewController.m // appXX-微信更多工具栏 // // Created by MRBean

  • iOS 开发之 - 关闭键盘 退出键盘 的5种方式

    iOS 开发之 - 关闭键盘 退出键盘 的5种方式  1.点击编辑区以外的地方(UIView) 2.点击编辑区域以外的地方(UIControl) 3.使用制作收起键盘的按钮 4.使用判断输入字元 5.关于键盘遮蔽的问题 1,点击编辑区以外的地方(UIView) 这是一种很直觉的方法,当不再需要使用虚拟键盘时,只要点击虚拟键盘和编辑区域外的地方,就可以将键盘收起,下面程式码是在 UIView 中内建的触碰事件方法函式,您可以参考 Touch Panel / 触碰萤幕 / 压力感应器的基本使用方式一

  • iOS开发中音频视频播放的简单实现方法

    前言 我们在平时的iOS开发中,音视频的播放有很多种,目前系统的自带的都属于 AVFoundation 框架,更加接近于底层,所以灵活性很强,更加方便自定义 还有就是第三方音视频视频播放,特点是功能强大,实现简单,支持流媒体,下面来逐一介绍,给大家参考学习,下面来一起看看详细的介绍吧. 播放系统音效或者短音效 注意: 这里的资源长度最多30秒 资源必须在 Target --> Build Phases --> Copy Bundle Resources 引入资源文件,否则获取不到文件 if l

  • IOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解 在实际的开发需求时,有时候我们需要对某些对象进行打包,最后拼接到参数中 例如,我们把所有的参数字典打包为一个 字符串拼接到参数中 思路:利用系统系统JSON序列化类即可,NSData作为中间桥梁 //1.字典转换为字符串(JSON格式),利用 NSData作为桥梁; NSDictionary *dic = @{@"name":@"Lisi",@"sex":@"m",@"tel&qu

  • IOS开发中加载大量网络图片优化方法

    IOS开发中加载大量网络图片如何优化 1.概述 在IOS下通过URL读一张网络图片并不像其他编程语言那样可以直接把图片路径放到图片路径的位置就ok,而是需要我们通过一段类似流的方式去加载网络图片,接着才能把图片放入图片路径显示.比如: -(UIImage *) getImageFromURL:(NSString *)fileURL { //NSLog(@"执行图片下载函数"); UIImage * result; NSData * data = [NSData dataWithCont

  • iOS开发支付宝支付成功返回字符串的处理操作

    { memo=""; result="partner=\"311811\"&seller_id=\"nse@gmail.com\"&out_trade_no=\"S005372\"&subject=\"\U522b\U5885\U8ba2\U5355\"&body=\"\U5885\"&total_fee=\"0.1\"

  • 浅谈iOS开发中static变量的三大作用

    (1)先来介绍它的第一条也是最重要的一条:隐藏 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性.为理解这句话,我举例来说明.我们要同时编译两个源文件,一个是a.c,另一个是main.c. 下面是a.c的内容 char a = 'A'; // global variable void msg() { printf("Hello\n"); } 下面是main.c的内容 int main(void) { extern char a; // extern v

  • IOS开发基础之二维数组详解

    IOS开发基础之二维数组详解 首先我们知道OC中是没有二维数组的,二维数组是通过一位数组的嵌套实现的,但是别忘了我们有字面量,实际上可以和C/C++类似的简洁地创建和使用二维数组.这里总结了创建二维数组的两种方法以及数组的访问方式. 通过字面量创建和使用二维数组(推荐) // 1.字面量创建二维数组并访问(推荐) NSArray *array2d = @[ @[@11,@12,@13], @[@21,@22,@23], @[@31,@32,@33] ]; // 字面量访问方式(推荐) NSLog

  • 解决IOS开发空字符串的方法

    解决IOS开发空字符串的方法 实例代码: -(Boolean) isEmptyOrNull:(NSString *) str { if (!str) { // null object return true; }else if(str == Null){ return true; }else if([str isKindOfClass:[NSNull class]]){ return true; }else { NSString *trimedString = [str stringByTrim

随机推荐