[0072] 为使本发明实现的技术手段、创作特征、达成目的与功效易于明白了解,下面结合附图对本发明作进一步的说明。
[0073] 如图1所示,一种iOS下移动APP安全防护系统主要包含以下五个安全模块:键盘信息的安全输入模块、用户数据安全存储模块、应用敏感信息安全保存模块、代码混淆模块和安全热更新模块。以下对各模块进行详细描述:
[0074] (1)安全键盘模块:该功能包括防攻击者通过点击坐标获取输入信息攻击,防止键盘缓存保存用户敏感信息,以及键盘信息输入时录屏接口的监听。
[0075] (2)用户数据安全保存模块:该模块功能对常用的本地存储数据文件类型进行了安全保护,包括数据库文件和普通文件。
[0076] (3)应用敏感信息安全保存模块:针对应用敏感信息,设计实现SSKeychain对应用敏感信息进行保存,另外,对保存应用信息plist文件也进行加密。
[0077] (4)代码混淆模块:该模块功能对应用源代码进行混淆,包括方法名混淆,类名混淆和文件名混淆。
[0078] (5)安全热更新模块:该模块对热更新脚本从服务器安全获取和本地安全保存。
[0079] 一种iOS下移动APP安全防护系统的实现方法,具体包括如下步骤:
[0080] 步骤1.启动安全键盘模块,具体实现如图2:
[0081] 1-1监听用户输入事件
[0082] 该过程为当用户使用UITextfield控件输入信息时,监听键盘的弹出事件,其主要实现方法是使用KVO技术监听键盘弹出。
[0083] 其实现过程如下:
[0084] 首先创建一个观察者,;
[0085] 然后给观察者添加观察内容,键盘的监听事件有四种状态:
[0086] UIKeyboardWillShowNotification键盘即将显示;
[0087] UIKeyboardDidShowNotifition键盘已经显示;
[0088] UIKeyboardWillHideNotification键盘即将隐藏;
[0089] UIKeyboardDidHideNotification键盘完全隐藏;
[0090] 本文需要监听UIKeyboardWillShowNotification键盘即将显示事件,添加完成后,即完成了对键盘输入的监听。在控制器viewDidLoad方法中使用addObserver添加观察者,@selector代表观察者触发事件后回调后方法,name代表观察者的触发事件,本过程主要对键盘即将显示事件进行观察。
[0091] 1-2拦截系统键盘显示
[0092] 当UIKeyboardWillShowNotification键盘即将显示事件触发时,系统会直接调用系统keyboard进行显示,为了能够显示本文设计的安全键盘,需要对系统键盘进行拦截,并替换成安全键盘,在步骤1-1中的keyboardWillShow方法中添加拦截代码即可实现系统键盘的拦截。
[0093] 其具体实现过程如下:在iOS系统中支持键盘输入的控件有UITextfield和UITextView,在这两个控件中有FirstResponder(第一响应者)的属性,当用户点击输入框时,系统先调用resign FirstResponder方法取消UITextField第一次响应者的属性,当该属性被取消,系统键盘便会隐藏,达到阻止系统键盘弹出目的。
[0094] 1-3检测是否存在录屏进程
[0095] 该过程检测是否存在录屏进程的调用,如果存在则停止安全键盘启动,并通知用户存在恶意录屏。
[0096] 检测App是否存在录屏进程的实现方法有以下两种:
[0097] 1.遍历App应用的所有framework,检测是否包含了ReplayKit框架。在iOS系统中,App的可执行文件以mach-O格式进行保存,其文件结构如图3所示,App在启动时通过load Commands将所有框架(例libobjc.A.dylib,libsystem等)动态链接到App中,遍历mach-O文件中load commands,判断App是否包含Replaykit框架。该方法通过检测整个App是否调用replaykit的方式来判断是否存在录屏进程,判断过于严格,易于造成误判。
[0098] 2.通过检测Replaykit的方法调用判断是否存在录屏进程,运行时再次判断,进一步消除上述方法的误判。其原理是:Object-C是动态语言,程序中的方法调用不是编译时决定,而是运行时,其动态性实现的主要技术是Runtime机制,简称运行时,是一套由纯C代码编写的API,在Object-C中一个类的数据结构为结构体如下代码所示,其中包含了类名name和其所有的方法名数组method_list,所以该检测过程只需要遍历method_list方法列表中所有的方法名,即可以判断是否存在恶意调用录屏进程监听键盘输入;其主要实现过程如下:在Replaykit中RPScreenRecord是录屏功能的操作对象,其中inti方法为RPScreenRecorder对象的创建方法,startRecordingWithMicrophone是RPScreenRecorder启动录屏方法。本文在安全启动时,使用runtime机制,遍历RPScreenRecorder对象中所有方法是否存创建和启动录屏两个方法,可达到判断是否存在录屏进程的目的。
[0099] 开发者可以根据App的安全要求选择其中两个方法的一种对是否存在录屏进程进行判断。
[0100] 1-4键盘按键随机布局
[0101] 该过程通过对键盘上的按键布局进行随机化处理,有效防止攻击者通过用户点击的坐标推断出按键信息,其基本原理是将所有字符按照标准键盘排布的顺序加入到数组中,然后对该数组进行随机排列处理如图4所示。
[0102] 首先创建一个标准键盘数组保存原键盘布局信息,然后使用arc4random函数产生0到标准键盘数组总个数中的随机数,再创建一个数组保存随机后的数组,将随机数K作为标准键盘数组的下标,顺序放入随机以后的数组中,为了防止下次删除数组越界,将标准键盘数组中最后的元素放入刚取出的位置,并删除最后一个元素,如此循环,直至标准键盘数组为空,键盘随机排序完成。
[0103] 1-5键盘和输入信息显示
[0104] 本过程为显示安全键盘显示的过程。本发明提出的安全键盘是基于UIView和UIButton两种控件实现,具体实现如下:
[0105] ①将键盘字符数组使用UIButton控件显示,并使用xib模板来实现UIButton布局,如图5所示。
[0106] ②创建保存UIButton点击输入的字符数组。
[0107] ③对每一个UIButton控件添加点击事件,并再创建一个新数组保存点击UIButton对应的字符。
[0108] ④将字符数组合并成字符串,iOS负责系统输入的主要控件有UITextField和UITextView,所以在UITextField中的text属性中提取字符,合并成字符串,即实现了键盘输入信息的显示。
[0109] 步骤2、用户数据安全保存
[0110] 2-1SQLite数据库安全存储
[0111] 本发明对SQLite数据库加密提供两种方案:①首先对数据进行加密,加密以后再保存到数据库当中。②将数据库sqlite文件转换成二进制,对sqlite的二进制文件进行加密,如图6所示,开发者可以根据需求进行调用。
[0112] (1)对数据库中的数据进行加密
[0113] 该方法实现包括数据加密模块、解密模块和数据库读写三部分。数据加解密采用iOS自带的加密框架CommonCryptor进行加密,该框架提供多种对称加密算法,同一时间内,开启多个线程供不同的CommonCryptor对象进行使用,且保证线程安全。
[0114] 首先使用getCString函数转将字符串密钥转换成AES密钥的形式,buffer代表申请保存密文的空间,然后调用iOS中CommonCrypor中的AES加密函数进行加密,最后以NSData数据类型返回密码。另外,数据库写入模块本文使用FMDB,它是一款简洁、易用的数据库封装库,其本质是对libsqlite3框架进行封装,并且它对于多线程的并发操作进行了处理,所以是线程安全的。
[0115] (2)对数据库文件进行加密
[0116] 该方法使用sqlcipher框架进行加密,该框架是第三方开源的,具有跨平台,加密效率高的优点。首先输入数据库地址,然后创建SQLite数据库,用sqlite3_exec函数进行加密。
[0117] 2-2文件安全存储
[0118] 对于小文件,因为其内存小可直接使用对称密钥进行加密,加密过程如图7中①所示:因为文件类型多种多样,需要将各类型的文件转换成统一的二进制数据格式,在Object-C中,NSData是对数据进行包装的对象,其以二进制数据格式保存在应用当中,它屏蔽了数据之间的差异,文本、音频、图像等数据都可使用NSData存储。
[0119] 把文件转换成二进制文件以后,使用非对称加密算法对二进制文件进行加密,因为AES是机密性好,加密效率高,所以本文采用AES算法对文件进行加密。另外,在加密的过程密钥是加密过程安全的保障,本文中的密钥可以由开发人员在开发阶段保存在App中,也可以由用户输入。
[0120] 对于视频,音频等大文件,由于移动端计算能力不高,如果直接转成NSData后加解密,不仅需要等待较多时间,而且消耗大量CPU和内存进行计算。针对该问题,本文提出的解决方案如图7中②所示:使用iOS系统提供的压缩API(createZipFileAtPath)对文件进行压缩,然后选择文件对应编码方式使用dataUsingEncoding方法将文件转化成NSData,最后使用base64编码进行加密。
[0121] 步骤3、App应用敏感数据安全保存
[0122] 3-1安全plist文件保护
[0123] 对于开发者自己创建的plist文件,可直接转为字符串进行加密处理,使用mainBundle方法找到App文件中开发者创建的plist文件地址,调用stringWithContentsOfURL将plist文件中的内容转化成NSString字符串格式,然后使用AES进行加密,并把密文写入ciphertext文档中,最后,使用NSFileManager文件管理者对象删除原plist文件。
[0124] 步骤4、代码混淆加固
[0125] 本发明提出的App源代码代码混淆分为关键字提取,创建数据库,混淆三个步骤,下文对这三步进行详细描述。
[0126] 4-1关键字提取
[0127] 在iOS应用编写过程中,其存在文件名,类名,协议名,函数名四类关键字,该过程需要对这四类关键字进行准确提取。
[0128] (1)文件名获取:在一个iOS应用中包含.framework、.a、.m、.h等类型的文件,其中.framework和.a属于框架型文件是公开的,不需要对其进行混淆,本文的目标是对”.h”和”.m”文件进行混淆。在shell命令中,可以使用find命令获取工程目录下所有的文件。
[0129]find $ROOTFOLDER-type f|sed"/\/\./d">f.list
[0130] 然后使用cat指令从文件中提取文件名。
[0131] cat f_rep.list|awk-F/'{print$NF;}'|awk-F.'{print$1;}'|sed"/^$/d"|sort|uniq)[0132] (2)类名获取:在Object-C中,.h文件声明了所有的方法名,.m文件实现.h中声明的方法。该步骤需要提取.h和.m所有的方法名,使用“@interface”字段快速定位到类名,使用grep指令其中sort参数为了排序;因为.h和.m中方法名会重复,所以加入uniq参数去重。
[0133]
[0134] (3)协议名获取:在Object-C中,协议是一种特殊的程序设计结构,用于声明专门被别的类实现的方法。可以使用“@protocol”关键字,从.h文件中提取出所有协议。
[0135]
[0136] (4)函数名获取:在Object-C中,函数名以“-()”开头,并以“;”或者“{”结尾,因此,以“-()”和”;”,”{”为关键字,提出两个关键字中的内容,并去除内容中变量名即为函数名,但是,”.h”可能存在”.m”中函数名的声明,两个文件找到的函数名可能会重复,所以需要加入uniq关键字去重。
[0137]
[0138] 4-2创建数据库
[0139] 本发明采用SQLite数据库来保存关键字,SQLite具有支持多个主流的操作系统;其核心引擎本身不依赖第三方软件;不需要安装;所有信息(例如表,视图,触发器等)都包含在一个文件内等优点。创建对应表的字段如下,src保存原关键字,des保存混淆后名字。
[0140] 表4-1混淆数据库表
[0141]src原关键字 des混淆后的关键字
[0142] 4-3对关键字进行混淆
[0143] 为满足混淆后的关键字不可逆,且长度相同的需求,文本采用MD5算法对原关键字进行混淆,该算法具有压缩性、计算效率高、抗修改性、强抗碰撞的特点,符合混淆不可逆且安全的需求。其实现过程如下:首先提取数据库中的src字段内容,调用shell命中的md5sum函数对src中的内容进行MD5计算,完成后将MD5值存入des字段,其代码如下:
[0144] echo-n'需要混淆的字符串'|md5sum|cut-d”-f1
[0145] 步骤5、安全热更新
[0146] 5-1热更新脚本安全下发
[0147] 在应用请求服务器更新脚本时,因为JavaScript脚本可以调用任意Object-C方法,权限非常大,如果传输过程代码被攻击获取或篡改,对App会造成较大的威胁。另外,脚本中可能包含应用敏感信息,所以脚本内容也必须具有保密性,本发明设计的热更新脚本安全下发方案如图8所示,设计传输过程如下:
[0148] ①使用一个会话秘钥key对脚本文件进行加密,得到加密脚本。
[0149] ②对脚本文件进行一次MD5运算,得到脚本文件的信息摘要。
[0150] ③使用服务器的私钥对会话秘钥key进行加密,得到加密key。
[0151] ④同时也用私钥对过程②的MD5值进行加密,得到加密MD5。
[0152] ⑤将加密key,加密脚本,以及加密MD5发送至客户端。
[0153] ⑥客户端使用服务器公钥对加密key进行解密,得到key。
[0154] ⑦客户端使用公对加密MD5解密,得到MD5。
[0155] ⑧使用key解密得到脚本文件。
[0156] ⑨客户端对脚本文件进行一次MD5操作。
[0157] ⑩对比过程⑦和过程⑨中的MD5,判断脚本在传输过程中是否遭到修改。
[0158] 本发明使用https传输协议对以上过程进行实现。
[0159] 5-2热更新脚本本地安全
[0160] 针对脚本文件在本地存在被篡改的威胁,本发明提出了以下方案如图9所示。当客户端调用脚本文件时,本方法会对脚本文件进行一次MD5计算,并将计算结果发送至服务器进行验证,即在5-1过程⑤加入脚本安全验证的过程,只有服务器验证通过,才可以执行脚本文件中的内容。