Cocos2d-x 资源加密解密总结

本文乃Siliphen原创,转载请注明出处:http://blog.csdn.net/stevenkylelee

本文针对的是cocos2d-x 3.4 版本进行研究。

做加密解密的思路

加密解密算法的简单介绍

首先,加密解密应该是一个单独的话题,一般不会涉及具体使用的引擎、框架和技术。

加密算法有Base64,DES等。

Base64的原理类似于凯撒密码,啥是凯撒密码呢,就是一个字符用另一个字符来代替。

比如:a用i代替,b用k代替,以此类推。加密和解密的过程就是一个互相映射的过程。

DES是一种使用密钥的加密算法。

DES和Base64这种无密钥的算法在使用上的区别是:

DES算法本身是可以不保密的,只要保密密钥即可,密钥才是解密的关键。

Base64如果用于加密的话,算法本身就是密钥。要保密算法。

MD5,SHA等是摘要算法。

Base64,DES都可以把密文还原出明文。

而MD5,SHA则不能对算法作用后的输出还原出原始数据。

摘要算法一般做身份验证。

我们做资源加密是要选择能把密文还原出明文的算法。

设计自己的加密解密算法

这属于密码学的内容了,可深可浅。

可以借鉴凯撒密码的原理自己对每个字节的内容进行映射来加密。

也可以对1字节,2字节,4字节的数据,用某个数进行异或运算来加密。

异或的特性是,用数A对内容B进行异或得到内容C,再用数A对内容C异或可以得到内容B。

这个特性可以被用来加密。同时,数A的作用就是密钥了。

设计的加密算法不同,加密算法的使用的接口也不同。

如果是用上面的2种思路做加密算法的话,加密算法的实现可以“in place”操作,

就是可以直接在密文所在的内存进行解密,不单独分配内存来保存解密后的数据。

如果加密算法很复杂,无法“就地还原”,就需要新申请内存来保存解密数据。

当然,执行速度一般是”就地还原“快。

我觉得,如果可以的话,最好是自己设计加密算法。

使用现成的DES之类的算法,密钥是关键。

如果是自己设计一个用密钥加密的算法,密钥和算法本身都是不公开的。

破解者要获取资源明文要经过如下步骤:

1.在程序中找到密钥的常量。

2.看懂反出来的汇编还原出算法,或者想办法利用加密算法的汇编代码。

其中步骤2会加大解密者解密的难度,这是自己设计加密算法比用现成的DES之类著名算法的好处。

加密解密的运用机制

我见过有一些人加密是对字段内容进行加密。

比如,他用xml保存数据,他只对保存的值进行加密。

内容类似这样 <Entity Hp = "密文" AttackValue = "密文" >

这并不是一种好的运用加密的方式,因为这种方式会:

1.透露程序的配置文件结构。XML、json等。

2.透露了程序可能使用的数据结构。看以上内容可猜想Entity实体类有2个字段,Hp(血量),AttackValue(攻击力)

更彻底的加密方式是,对整个xml、json等文件进行加密。

这样别人就不会知道关于你的数据的一丁点信息。

这种做法不是直接用数据解析库封装的类似LoadFile的函数直接读取文件。

而是,先把加密文件用文件读取方法读入内存,在内存解密后,再把解密数据传给解析库的解析函数。

这种做法要求解析库有对内存进行解析的接口。

比如,若用XML解析库,就会弃用LoadFile,要求有Parse方法。

有一种情况可能无法对整个数据文件进行加密。

就是使用sqlite等数据库的时候,这时候只能对字段进行加密了。

有些人设计加密机制会要求配置程序本身。

比如:程序需要一个配置(一个开关变量或者条件编译)来决定是否对资源进行解密。

发布时,把资源都加密好,开启程序对资源的解密。

开发时,资源不必加密,屏蔽程序对资源的解密。

这种做法需要来回设置解密开关,比较繁琐。

有一种实现思路更有扩展性、更灵活、使用更方便。

那就是自己设计文件头。

熟悉Win32编程的人可能会知道PE文件格式。

Windows运行一个exe之前,会检查PE文件头,

取得EXE文件的数据常量、代码区块等信息后,系统才能正确执行一个EXE。

我们可以设计一个加密文件头,加密文件头有一个字段标识该文件是否是被加密过的。

解密算法可以通过判断加密头的标识符来决定是否进行解密、采用哪种解密算法等。

这是一种数据驱动式的解密机制,解密信息都保存在加密数据本身中。

对于没有被加密过的数据,程序判断没有文件加密头标识,就不执行解密。

这样,程序可以同时读取未加密的数据和已经加密的数据,而不需要对程序进行任何修改。

注意:加密头的标识符应该足够特殊,保证和未加密的数据不会产生冲突。

若未加密的数据刚好出现了加密头的内容,那么程序就会对未加密的数据进行解密。

在Cocos2d-x 中做加密解密的研究过程

我的项目配置是用CSV文件。解析器,用的是我自己写的CSV解析器:

CSV文件格式解析器的实现:从字符串Split到FSM

在游戏中这部分的解密,比较容易实现,就是对整个文件加密,

游戏启动时把加密文件读入内存进行解密,然后把解密数据传到解析器进行解析。

一些由游戏产生的需要保存的数据,我用XML进行保存。加解密思路也如上。

但是,对于图片、动画,粒子、cocostudio1.6导出的UI 等数据,加密就不那么简单了。

因为,像 Sprite::create 这样的接口,并没有提供一个从内存获取纹理数据来初始化精灵的方式,

而是直接从磁盘文件中读。用户在外部是无法干预文件数据的读取载入的。

游戏资源的加密要怎么做?——只有修改引擎了。- -!

我觉得,修改引擎并不是一个好的做法。

引擎应该由引擎提供商来维护,而不是靠用户自己来动手。

用户自己动手会造成项目维护升级困难。

自己把引擎改得乱七八糟,想升级引擎到新的版本会变成很麻烦。

就算是修改了一点,升级引擎版本一次,就要做一次修改,这样也很麻烦。

要修改引擎,首先要跟踪调试,

以cocos2d-x 3.4 作为试验版本,从Sprite::create入口,一步步跟下去,

看看引擎是在哪里载入文件数据的。

经过调试跟踪,Sprite::create的调用堆栈如下:

getData

FileUtilsWin32::getDataFromFile

Image::initWithImageFile

TextureCache::addImage

Sprite::initWithFile

Sprite::create

在windows上,精灵载入图片,是调用到了

CCFileUtils-win32.cpp 这个文件中的

static Data getData(const std::string& filename, bool forString) 函数。

这个函数是一个非类成员静态函数。

再调试下其他的数据载入,cocostudio1.6做的动画的调用堆栈是:

cocos2d::FileUtilsWin32::getFileData

cocostudio::DataReaderHelper::addDataFromFile

cocostudio::ArmatureDataManager::addArmatureFileInfo

经过了多种文件类型载入的跟踪调试后,总结,

基本上文件的载入函数有2个,都在CCFileUtils-win32.cpp文件中,

1.FileUtilsWin32::getFileData

2.getData

要做解密的话,就是修改这2个函数了。

值得注意的一点是:getData函数的签名是:

static Data getData(const std::string& filename, bool forString)

forString这个参数,用于标识读入的文件是不是一个文本文件。

如果forString为真的话,buffer就要多分配一个字节,用来放置C语言的字符串结束符 \0

截图一下引擎的代码:

要做解密,我们的解密数据内存也要用forString来判断是否多分配一个字节的内存。

FileUtils单件类,很多函数是虚函数。FileUtils::getInstance,

在Windows平台上,返回的是 FileUtilsWin32子类对象。

在Android平台上,返回FileUtilsAndroid子类对象。

Cocos2d-x 3.4 实现在Windows和Android平台上的解密需要修改2个文件:

Windows 平台的:cocos\platform\win32\CCFileUtils-win32.cpp

Android 平台的:cocos\platform\android\CCFileUtils-android.cpp

这2个文件里面都有 getData 和 getFileData 函数,都需要修改之。

文件数据的读取在不同平台上有不同的实现,

如果要在目标平台上做资源加密,就需要修改目标平台上的读取实现。

FileUtils是一个文件读取基类,提供有默认的实现,一些平台会提供特定的实现。

通过多态,FileUtils让我们的游戏客户端代码不需要对特定平台做特定处理,

也不需要关心FileUtils子类的类型。

加密解密支持工具

一般要做资源数据加密,大体会做2件事:

1.写一个工具,能对磁盘文件进行加密。这个工具,可能需要遍历文件夹、可批量选择文件等功能。

2.在软件程序中加入解密功能,对工具加密后的数据进行解密。

工具能方便操作、提高生产力,很重要。

这里,我自己做了2个工具。

1.对cocos2d-x引擎进行修改和恢复的工具,使其具备解密功能。如下:

2.对磁盘文件进行加密解密的工具,方便打包时的批量筛选操作。如下:

加密解密的额外开销

做了资源加密会降低程序的性能,原因很简单,需要对文件数据进行额外的处理。

稍微复杂一点的加密算法,可能要申请内存空间来保存解密数据。delete , new 都是耗时操作。

资源的加密也可能会使得apk包体体积增大。这是为什么呢?

原因是,用Cocos2d-x 开发,资源会有很多
*.plist *.ExportJson *.tmx 等文件。

plist 可能是配置,也可能是粒子。

*.ExportJson 等文件是 Cocostudio1.6 做出的动画、UI 导出文件。

*.tmx
是Tilemap输出的地图格式。

以上说的这些文件,都是用文本存储数据的,可以用Windows记事本打开查看内容。

apk包实际上是一个压缩包,压缩算法对于有大量冗余数据的文件压缩率是很高的。

我之前写过一篇关于压缩算法的文章《文件压缩与解压:哈夫曼编码》有兴趣的同学可以看看。

我做过一个试验,600多KB的 UI *.plist *.ExportJson 文件,打成apk包后,实际上只占60多KB。

这是因为压缩算法能对这些配置的文本文件有很高的压缩率。

如果我们的加密算法会降低冗余数据。

比如:一个文件的内容是“111111....",10万个1。

我们的加密算法为了增加安全性,会把这些内容加密成为:"sfsadfsa...."。

解密者很难从无规律的不重复的数据推出原先的”111111....“的内容,

但同时对这样的数据,压缩率也会很低。

我之前设计了一个使用密钥加密的算法,会消除冗余数据,

对于都是同样的一个字符的内容,可以加密成一个看似无规律的乱七八糟的内容,

其实还是有规律可言,只是无规律循环节很大而已。

然后,这些加密后的数据,几乎就不能压缩了。

加密资源之后输出的apk包相比没加密资源的包,体积增加不少。

对于这种情况,可以仅对图片等关键资源加密,而不对非关键性的文本文件加密。

或者降低算法的加密强度,保留数据冗余性。

时间: 2024-08-27 06:38:57

Cocos2d-x 资源加密解密总结的相关文章

cocos2dx加密解密资源

先加密游戏资源然后 改cocos2dx底层代码,在读取的时候进行解密 1 unsigned char* CCFileUtils::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize) 2 { 3 unsigned char * pBuffer = NULL; 4 CCAssert(pszFileName != NULL && pSize != NULL && pszM

手机游戏加密那点事儿_2d资源加密_1

本文章讲述利用cocos2d-x 开发手机游戏的一些加密心得.如有问题,请多指正. 更多信息详见:http://blog.csdn.net/chengyingzhilian/article/details/25540441 本文地址:http://blog.csdn.net/chengyingzhilian/article/details/25076419 好了,进入本文的主题--资源加密: 关于图片资源的打包当然是采用TexturePacker了.官方网址:http://www.codeand

cocos2dx游戏资源加密之XXTEA

在手机游戏当中,游戏的资源加密保护是一件很重要的事情. 我花了两天的时间整理了自己在游戏当中的资源加密问题,实现了跨平台的资源流加密,这个都是巨人的肩膀之上的. 大概的思路是这样的,游戏资源通过XXTEA加密方法对流的加密方式,有自己的密钥和标识,通过标识可知是否有加密,密钥是自己程序当中的.除非有密钥,否则很难通过解出正确的文件.经过加密后,加密文件也就是游戏资源放在resource的自己文件夹中,否则在xcode编译到趁机是会识别不了文件.在程序中cocos2dx底层加入解密过程,就可以把文

加密解密

在现代密码学中,加密方法大致可分为对称密钥加密(对称加密)和公开密钥加密(非对称加密). 一. 对称加密(Symmetric-key algorithm,或对等加密: Reciprocal cipher ) 对称加密,即加密和解密使用同一个密钥,或者知道一方密钥能够轻易计算出另一方密钥.其解密(decryption)算法等同于加密算法,也就是说,要还原对等加密的密文,套用加密同样的算法即可得到明文. 对称加密的速度比非对称加密快很多,在很多场合都需要对称加密. 对称加密又可分为分组密码(分组加密

加密/解密&利用OpenSSL构建私有CA

在互联网安全及个人隐私状况日益严峻的今天,加密技术变得尤为重要并且不可或缺.在密码雪中,加密是指将明文信息隐匿起来,使之在缺少特殊信息时不可读.本文所讲的主要是在互联网传输数据时所用的加密方式.我们都知道OSI&TCP/IP网络参考模型,通常我们会把这两个模型分为通信子网和资源子网两部分,但是在构建网络的初期,信息从发送端送达到接受端都非常困难所以在设计模型之初并没有考虑过多的安全因素,以至于通信子网和资源子网都没有涉及到数据加密的内容.为了解决这个问题,网景公司在资源子网和通信子网之间添加了半

加密 解密过程详解及openssl自建CA &nbsp;

            加密 解密过程详解及openssl自建CA 为了数据信息能够安全的传输要求数据要有一定的安全性那么数据的安全性包含哪些方面的特性呢?    NIST(美国信息安全署)做了如下的定义:    保密性:       1,数据的保密性 指的是数据或隐私不向非授权者泄漏                   2,隐私性  信息不被随意的收集    完整性:       1,数据的的完整性:信息或程序只能被指定或授权的方式改变不能被随意的             修改        

CocoStudio游戏发布后资源加密大致实现思路

截 止到目前,CocoStudio版本已经发展到1.5,各个子工具间也已经发生了巨大变化.但是,无论是动画编辑器,UI编辑器,场景编辑器还是 数据编辑器,它们生成(导出)的文件在商业开发中往往需要进行加密处理(当然,对于其中的一些部分加密也实在没有必要). 那么,版本发布时,如何对资源进行加密? 对此,以前官方没有给出任何回答.最近,我从cocoachina论坛上了解了几句,但是已经足够我们参考之用了.大致思路如下: NOTE: hanrea是cocoachina论坛中的一位高人,我有事经常与他

使用php mcrypt加密解密

数字签名:对数据和私钥进行hash运算得到消息摘要,连同消息本身一块发给客户端.数据签名强调客户端接收到的数据是来自特定服务端,服务端具有对数据不可否认性.客户端通过确认此次签名的正确性来判断拿到的消息是否来自特定服务端. 数据加密:对数据进行加密,有对称加密和非对称加密两种.PHP中常使用 mcrypt和openssl扩展对数据进行加解密.mcrypt常用在对称加密中,openssl常用在非对称加密中.另外在编程中还经常使用到一种单项散列加密算法,比如MD5,HASH,SHA1,passwor

加密解密原理,自建CA

目前数据的加密方式有3种:单向加密,对称加密,公钥加密(非对称加密),我们常见的加密算法有DES,MD5,SHA1...SHA512,RSA,都有各自不同的用处.简单介绍下这3中加密方式. 单向加密 通过某种Hash 函数对原始数据进行提取,提取得到一端固定长度的密文(不管文件有多大,密文长度不变),这段数据也常被称为数据指纹或特征码. 特点:1)单向加密,只能由原始数据得到特征码,而不能由特征码逆向推出原始数据. 2)雪崩效应,原始数据微小的改变会导致特征码巨大的变化 应用:常被应用于数字签名