iOS如何保证下载资源的可靠性

前言

有时需要在本地存储资源,并且从服务器下载资源,因为涉及到运行期间的安全性,有必要添加校验的逻辑,因此有了本文的一些思考。

ipa包被篡改的情况

首先思考的是ipa包的安全性问题。通过iTunes,我们可以下载ipa并且解压,修改包中的文件,再压缩成ipa包。

  • 1、如果开发者A拿到应用P的ipa包,修改其中的任何文件,都会导致签名失效,ipa包无法安装。(签名存放在.app文件的_CodeSignature文件夹)
  • 2、如果开发者B拿到应用P的ipa包,安装到自己手机中,再直接修改Bundle/Application 下的配置文件,此时应用P仍旧可以运行。
  • 3、如果开发者C拿到应用P的ipa包,修改其中的某些配置文件,用自己的证书重签名并通过其他渠道发布出去,ipa包可以正常安装。

应用在正常使用过程中,app包的文件是无法修改的,只有越狱的机子才会出现情况2;情况3中重签名的ipa包无法上传AppStore。
真机app安装目录是 var/mobile/Containers/Bundle/Application
沙盒目录是 var/mobile/Containers/Data/Application
类似的,模拟的安装目录同样在/Bundle下,沙盒在/Data下;

下载资源的验证

下载的资源存在沙盒目录,在未越狱的情况下,开发者并不能修改其中的文件。但是,下载资源通常使用http进行资源下载,http通过使用代理,可以很方便的修改下载的资源。为了保证下载资源的可靠性,采用了一套基于RSA算法的验证方案,具体的要点有:
1、开发者产生一对密钥:公钥和私钥,私钥保存在配置平台(后台),公钥放到客户端。
2、当文件上传到配置平台后,配置平台对文件进摘要(hash)得到md5str,并私钥对md5str进行签名得到signStr,然后把 文件和signStr下发给客户端。
3、客户端下载文件和signStr,计算文件的摘要(md5)得到md5str,用md5str和公钥验证signStr的有效性。

解释:
非对称加密算法的计算比较复杂 ,所以只对摘要(md5值)进行加密;
具体的流程图如下:

iOS的RSA算法

RSA算法的两种加密方式:

  • 公钥加密,私钥解密。(一般用于公钥持有方(客户端)向私钥持有者(后台)发送消息)
  • 私钥加密,公钥解密。(一般用于签名和验证,私钥加密相当于签名,公钥解密相当于验证)

苹果提供的Security.framework,有以下四个方法:

  • SecKeyEncrypt—encrypts a block of data using the specified key.(使用公钥对数据进行加密)
  • SecKeyDecrypt—decrypts a block of data using the specified key. (使用私钥对数据进行解密)
  • SecKeyRawSign—signs a block of data using the specified key.(使用私钥对数据签名)
  • SecKeyRawVerify—verifies a signature against a block of data and a specified key. (使用公钥对数字签名进行验证)

类比到OpenSSL,其提供了以下四个接口:

int     RSA_public_encrypt(int flen, const unsigned char *from,
                unsigned char *to, RSA *rsa,int padding);
int     RSA_private_encrypt(int flen, const unsigned char *from,
                unsigned char *to, RSA *rsa,int padding);
int     RSA_public_decrypt(int flen, const unsigned char *from,
                unsigned char *to, RSA *rsa,int padding);
int     RSA_private_decrypt(int flen, const unsigned char *from,
                unsigned char *to, RSA *rsa,int padding);

因为RSA算法的计算量较大,一般不会直接使用RSA对数据进行加密,而是对AES的密匙进行加密,再用AES对数据加密。
RSA算法原理 ,这里有一篇详细介绍RSA算法原理的文章。

数字签名的保存

拿到后台下发的签名后,就需要保存签名,可以选择:保存在文件中、保存到NSUserDefault、保存到数据库等。除此之外,是否可以保存在文件属性
写了一段代码进行测试:

    NSMutableDictionary *changedAttrDict = [[NSMutableDictionary alloc] init];
    [changedAttrDict setObject:@"loying" forKey:NSFileOwnerAccountName];
    [changedAttrDict setObject:@"NSFileGroupOwnerAccountName" forKey:NSFileGroupOwnerAccountName];
    [changedAttrDict setObject:[NSDate dateWithTimeIntervalSinceNow:3600] forKey:NSFileCreationDate];
    
    NSError *error;
    
    BOOL ret = [[NSFileManager defaultManager] setAttributes:changedAttrDict ofItemAtPath:encodedDataPath error:&error];

经过测试,NSFileCreationDate这个属性是可以修改的;
NSFileGroupOwnerAccountNameNSFileOwnerAccountName不能修改(真机为@"mobile");模拟器不可以修改两个属性,最大的可能性是因为模拟器运行产生的文件,权限不够修改文件属性;
createDirectoryAtPath:withIntermediateDirectories:attributes:这个方法同样有这个限制。
写入文件属性还有其他的限制,当文件在不同硬盘格式(HFS+ and FAT32)拷贝的时候,文件附带的属性可能会消失。

NSFileProtectionKey 是后台模式下的文件读写

为了开发方便,可以选择保存到NSUserDefault的方式。
新建NSMutableDictionary,用文件作为key,用FileConfig作为value。FileConfig是验证相关的属性封装,便于后续开发。

1、NSUserDefault所有的属性最终会写入Libary/Preference/下的plist文件中,所以NSUserDefault中不能存储敏感信息。

2、如果遇到错误:Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object
那是因为NSUserDefault只能存基本类型,如果dict里面存有自定义类型,需要先转成NSData再存储;(plist里面没有结构信息,只有key-value)

总结

任何手段都无法完全防止恶意的攻击,只能提高门槛。

附录

iOS使用Security.framework进行RSA 加密解密签名和验证签名
http://blog.methodname.com/da-zao-yin-xing-ji-jia-mi/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容