iOS动态部署之RSA加密传输Patch补丁
概要:这一篇博客主要说明下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补丁的更多相关文章
- iOS动态部署方案
转载: iOS动态部署方案 前言 这里讨论的动态部署方案,就是指通过不发版的方式,将新的内容.新的业务流程部署进已发布的App.因为苹果的审核周期比较长,而且苹果的限制比较多,业界在这里也没有特别多的 ...
- RSA加密传输代码示例
RSA加密传输代码示例 涉及敏感数据的传输,双方最好约定使用加密解密.那RSA非对称加密就大有作为了.服务端可以保留自己的私钥,发给客户端对应的公钥.这样就可以互相加解密了.php中rsa加解密实现: ...
- php RSA加密传输代码示例
涉及敏感数据的传输,双方最好约定使用加密解密.那RSA非对称加密就大有作为了. 服务端可以保留自己的私钥,发给客户端对应的公钥.这样就可以互相加解密了.php中rsa加解密实现: 首先要生成一对公钥私 ...
- php RSA加密传输代码示例(轉)
原文地址:http://www.cnblogs.com/firstForEver/p/5803940.html 涉及敏感数据的传输,双方最好约定使用加密解密.那RSA非对称加密就大有作为了. 服务端可 ...
- iOS and JAVA 的 RSA 加密解密 (转载整理 )
参考原文地址:http://www.cnblogs.com/makemelike/articles/3802518.html (至于RSA的基本原理,大家可以看 阮一峰的网络日志 的 RSA算法原理( ...
- Js参数RSA加密传输,jsencrypt.js的使用
注意几点: 1.参数传递的+号处理,在传输时会把+变成空格,不处理后端就报错了. 1.前段代码 <!DOCTYPE html> <html> <head> < ...
- iOS应用架构谈part4-本地持久化方案及动态部署
前言 嗯,你们要的大招.跟着这篇文章一起也发布了CTPersistance和CTJSBridge这两个库,希望大家在实际使用的时候如果遇到问题,就给我提issue或者PR或者评论区.每一个issue和 ...
- ssiOS应用架构谈 本地持久化方案及动态部署
本文转载至 http://casatwy.com/iosying-yong-jia-gou-tan-ben-di-chi-jiu-hua-fang-an-ji-dong-tai-bu-shu.html ...
- RSA加密原理使用方式签名验证
RSA加密原理使用方式签名验证 加密是网络传输中非常重要的一环,它保证了信息的安全性,让他人无法通过抓包来获取通讯的信息也无法通过伪造信息而实现对系统的入侵.其中最为常用的信息传递加密方式就是RS ...
随机推荐
- Jquery-UI使用
=创建form对话框弹出登录 首先引入css样式和js. <link rel="stylesheet" href="<%=path%>/css/demo ...
- Re 模块
re模块提供方法如compile, search, findall, match和其他的方法.这些函数是使用REGEX语法建立了一个模式来处理文本的. 第一个方法:search. 一个基本的搜索工作原 ...
- [LeetCode] Flip Game 翻转游戏
You are playing the following Flip Game with your friend: Given a string that contains only these tw ...
- [LeetCode] Combine Two Tables 联合两表
Table: Person +-------------+---------+ | Column Name | Type | +-------------+---------+ | PersonId ...
- [LeetCode] Minimum Depth of Binary Tree 二叉树的最小深度
Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...
- FPGA与simulink联合实时环路系列——实验三 按键key
实验三 按键key 实验内容 在FPGA的实验中,经常涉及到按键的使用,按键是必不可少的人机交互的器件之一,在这些实验中,有时将按键的键值读取显示到数码管.LCD或者是通过串口传送到PC的串口助手上进 ...
- C语言中struct位域的定义和使用
位域的定义和使用 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又 ...
- background-size
语法: background-size:length|percentage|cover|contain length:设置背景图像的宽度和高度, 第一个值为宽度,第二个值为高度. 如果只设置一个值,则 ...
- [基础] Array.prototype.indexOf()查询方式
背景 最近在看Redux源码,createStore用于注册一个全局store,其内部维护一个Listeren数组,存放state变化时所有的响应函数. 其中store.subscribe(liste ...
- OpenCV二值图像孔洞填充的一个简单方法
在Matlab下,使用imfill可以很容易的完成孔洞填充操作,感觉这是一个极为常用的方法,然而不知道为什么OpenCV里面却没有集成这个函数.在网上查了好多关于Opencv下的孔洞填充方法,大部分使 ...