概要:这一篇博客主要说明下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需求,可以重新下载等等处理。

iOS动态部署之RSA加密传输Patch补丁的更多相关文章

  1. iOS动态部署方案

    转载: iOS动态部署方案 前言 这里讨论的动态部署方案,就是指通过不发版的方式,将新的内容.新的业务流程部署进已发布的App.因为苹果的审核周期比较长,而且苹果的限制比较多,业界在这里也没有特别多的 ...

  2. RSA加密传输代码示例

    RSA加密传输代码示例 涉及敏感数据的传输,双方最好约定使用加密解密.那RSA非对称加密就大有作为了.服务端可以保留自己的私钥,发给客户端对应的公钥.这样就可以互相加解密了.php中rsa加解密实现: ...

  3. php RSA加密传输代码示例

    涉及敏感数据的传输,双方最好约定使用加密解密.那RSA非对称加密就大有作为了. 服务端可以保留自己的私钥,发给客户端对应的公钥.这样就可以互相加解密了.php中rsa加解密实现: 首先要生成一对公钥私 ...

  4. php RSA加密传输代码示例(轉)

    原文地址:http://www.cnblogs.com/firstForEver/p/5803940.html 涉及敏感数据的传输,双方最好约定使用加密解密.那RSA非对称加密就大有作为了. 服务端可 ...

  5. iOS and JAVA 的 RSA 加密解密 (转载整理 )

    参考原文地址:http://www.cnblogs.com/makemelike/articles/3802518.html (至于RSA的基本原理,大家可以看 阮一峰的网络日志 的 RSA算法原理( ...

  6. Js参数RSA加密传输,jsencrypt.js的使用

    注意几点: 1.参数传递的+号处理,在传输时会把+变成空格,不处理后端就报错了. 1.前段代码 <!DOCTYPE html> <html> <head> < ...

  7. iOS应用架构谈part4-本地持久化方案及动态部署

    前言 嗯,你们要的大招.跟着这篇文章一起也发布了CTPersistance和CTJSBridge这两个库,希望大家在实际使用的时候如果遇到问题,就给我提issue或者PR或者评论区.每一个issue和 ...

  8. ssiOS应用架构谈 本地持久化方案及动态部署

    本文转载至 http://casatwy.com/iosying-yong-jia-gou-tan-ben-di-chi-jiu-hua-fang-an-ji-dong-tai-bu-shu.html ...

  9. RSA加密原理使用方式签名验证

      RSA加密原理使用方式签名验证 加密是网络传输中非常重要的一环,它保证了信息的安全性,让他人无法通过抓包来获取通讯的信息也无法通过伪造信息而实现对系统的入侵.其中最为常用的信息传递加密方式就是RS ...

随机推荐

  1. BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5217  Solved: 1233 ...

  2. webform控件

    简单控件: 1.Label 会被编译成span标签 属性: Text:文本内容 CssClass:CSS样式 <asp:Label ID=" CssClass="aaa&qu ...

  3. html5 自定义标签取值

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. AngularJS的基础元素应用

    <!doctype html> <!-- 标记ng-app告诉AngularJS处理整个HTML页并引导应用 --> <html ng-app> <head& ...

  5. neo4j关闭和开启密码访问权限

    本例:neo4j-enterprise-2.3.1版本 neo4j默认安装是开启访问密码验证 可以发现,在conf/下的neo4j-server.properties配置文件 # Require (o ...

  6. ThinkPHP 多语言

    1.注意区分项目语言包和系统语言包 2.实现语言包和数据库语言同步切换 实用链接: ThinkPHP完全开发手册3.1 多语言 thinkphp3.1 多语言简单demo 总结ThinkPHP使用技巧 ...

  7. C#面向对象设计模式纵横谈——4.Builder 生成器模式(创建型模式)

    动机 (Motivation) 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是它们组合 ...

  8. RocketMQ原理解析-Consumer

    consumer 1.启动 有别于其他消息中间件由broker做负载均衡并主动向consumer投递消息,RocketMq是基于拉模式拉取消息,consumer做负载均衡并通过长轮询向broker拉消 ...

  9. 以最简单方式学习Linux

    有很多关于Linux的书籍,博客.大多数都会比较"粗暴"的将一大堆的命令塞给读者,从而使很多.NET程序员望而却步.未入其门就路过了. 所以我设想用一种更为平滑的学习方式, 就是在 ...

  10. ARM-汇编指令集(总结)

    ARM汇编指令集 指令.伪指令 (汇编)指令:   是机器码的助记符,经过汇编器编译后,由CPU执行. (汇编)伪指令:用来指导指令执行,是汇编器的产物,最终不会生成机器码. 有两种不同风格的ARM指 ...