概要:这一篇博客主要说明下iOS客户端动态部署方案中,patch(补丁)是如何比较安全的加载到客户端中。

在整个过程中,需要使用RSA来加密(你可以选择其它的非对称加密算法),MD5来做校验(同样,你也可以选择其他的算法)。

iOS客户端中RSA加解密的例子不是很多,我在网络上寻找了一些开源代码,发现揭秘算法有误。我就在其基础上做了修改,修复了问题。并且我重新整理了一份,并且支持cocoapod接入,下面是github地址。以后我还会详细的说明RSA加密的原理,以及github上代码实现。

https://github.com/qianhongqiang/RSAEncryptor

生成RSA公私钥文件

RSA公私钥声称可以参考下面的文章,照着一步步做就是了。其中,公私钥长度建议1024位以上,我自己则采用了2048位的。

http://blog.csdn.net/yi_zz32/article/details/50097325

使用.der后缀的公钥和.p12为后缀的私钥作为秘钥对,对尚未加密的patcher进行加密。

MD5校验

因为网络传输存在不稳定性,倘若传输中某个字节出现了错误,那么加载patch后肯定会运行失败,在这种情况下,我们是不能加载patcher的。游戏游戏在下载patch后,都会提示正在进行MD5校验(或其他算法校验),都是这个道理。MD5的功能只是单纯的进行校验。我直接把使用的代码贴出来了,比较短。需要倒入库#import <CommonCrypto/CommonDigest.h>,你可以直接拷贝。

+(NSString*)fileMD5:(NSString*)path
{
NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
if( handle== nil ) return @"ERROR GETTING FILE MD5"; // file didnt exist CC_MD5_CTX md5; CC_MD5_Init(&md5); BOOL done = NO;
while(!done)
{
NSData* fileData = [handle readDataOfLength: 256 ];
CC_MD5_Update(&md5, [fileData bytes], (uint32_t)[fileData length]);
if( [fileData length] == 0 ) done = YES;
}
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5_Final(digest, &md5);
NSString* s = [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
digest[0], digest[1],
digest[2], digest[3],
digest[4], digest[5],
digest[6], digest[7],
digest[8], digest[9],
digest[10], digest[11],
digest[12], digest[13],
digest[14], digest[15]];
return s;
}

生成加密后的Patcher

目前来说,我紧紧打算用patche做bug紧急修复的用途,没有打算直接使用它发布新功能,所以patcher中紧紧包涵脚本的文本,不包含图片等文件。

自己定义了流的生成与解析过程:

写入md5值的长度,我这里用1个字节表示,已经足够的长度来表示了。

NSMutableData *finalData = [NSMutableData data];//所有的data最后都写入这个data中

NSString *fileMD5 = [MD5 fileMD5:dataFileName];
NSData *md5Data = [fileMD5 dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger length = [md5Data length]; unsigned char bit8 = length & 0x000000FF;//提取低八位
[finalData appendBytes:&bit8 length:1]; [finalData appendData:md5Data];

最后在把RSA加密后的data拼接到finalData中,在把data输出到文件。这样patcher就搞定了。

解密patcher

patcher下载客户端后,就需要对patcher进行解析。解析就逆着patcher的生成过程就可以

NSData *decryptFileData = [NSData dataWithContentsOfFile:encryptFileName]; //获取文件的data

//读取文件的第一个字节,
int8_t v1;
[decryptFileData getBytes:&v1 range:NSMakeRange(0,1)];
//查看MD5值的长度
int getMG5Length = (int32_t)v1 & 0x0ff;
//查看md5信息
NSData *getmd5Data = [decryptFileData subdataWithRange:NSMakeRange(1, getMG5Length)];
NSString *fileMD5s = [[NSString alloc] initWithData:getmd5Data encoding:NSUTF8StringEncoding];
//获取真正的patcher文本的data
NSData *contentData = [decryptFileData subdataWithRange:NSMakeRange(1+getMG5Length, decryptFileData.length - 1 -getMG5Length)];

该有的信息全部存在了,只需要将data转成文本,再次md5跟校验值比较,是否一致,一致的话,那么这个patcher就是正常的,可以加载。如果不正常的话,那么根据app需求,可以重新下载等等处理。

最新文章

  1. 使用visual studio 调试android 程序 ,真机调试
  2. 关于SQL Cookbook里dept与emp表结构以及数据
  3. Linux平台延时之sleep、usleep、nanosleep、select比较
  4. nginx&amp;apache比较
  5. oracle 10g 学习之PL/SQL简介和简单使用(10)
  6. 2. scala中的数组
  7. 使用mysql函数 group_concat 一点需要注意的
  8. leetcode 19
  9. C#之装箱和拆箱
  10. UPDATE---修改表中数据
  11. jspsmart(支持中文下载)
  12. 多人合作开发启动activity-----规范问题
  13. cJSON 库的使用和优化
  14. 程序员的自我救赎---11.4:FileSystem文件服务
  15. PDF怎么旋转页面,只需几步轻松搞定!
  16. Windows 下 Mysql8.0.12 的安装方法
  17. SQL查询今天、昨天、7天内、30天 - 转
  18. [SDOI2009]Bill的挑战——全网唯一 一篇容斥题解
  19. 【树莓派】树莓派与XBMC及Kodi、LibreELEC插件(一)
  20. 得到scp命令的完整路径

热门文章

  1. spring3系列一
  2. 有关日期的函数操作用法总结,to_date(),trunc(),add_months();
  3. [LeetCode] 4Sum II 四数之和之二
  4. [LeetCode] Palindrome Pairs 回文对
  5. 请求如何进入ASP.NET MVC框架
  6. 类EF框架Chloe.ORM升级:只为更完美
  7. NPOI操作EXCEL(三)——反射机制进行excel表格数据的解析
  8. Gulp 入门
  9. 【转】fatal error C1900: “P1”(第“20081201”版)和“P2”(第“20080116”版)之间 Il 不匹配
  10. Nfs+Drdb+Heartbeat 数据存储高可用服务架构方案