在游戏发布之前,最好将图片加密,为apk/ipa加一层保护(虽然可能没用),涉及两个问题:
1. 如何对图片加密 2. 如何读取加密后的图片 1 2 下面详细说明。
对图片加密 Quick-3.3提供了pack_files.sh可以实现对图片加密,基本原理就是对每个图片使用xxtea加密算法对图片二进制数据进行加密,我们只需要提供密钥key和签名sign即可。具体用法如下:
# encrypt images
./pack_files.sh -i path/to/image -o output/dir -m files -ek encrypt_key_sample -es encrypt_sign_sample
各个参数的意义
参数 含义 -i 待加密的图片所在目录 -o 加密后的图片输出目录 -m files,输出为单个加密后的文件 -ek 指定加密密钥 -es 指定加密签名 如果执行正常,输出类似:
Pack source files in path path/to/img create output files in output/dir . done. 1 2 3 读取加密后的图片 暂时没有想到更好的办法,只好修改了CCImage.cpp的源文件去判断图片是否加密,如果加密了,首先对其解密,再生成CCImage对象。
// CCImage.cpp
// 首先包含xxtea的头文件,xxtea在cocos2dx已包含,无需单独提供,只需要正确引入即可 #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include "xxtea.h" #else #include "external/xxtea/xxtea.h" #endif
// 主要修改initWithImageData这个函数 bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen) { bool ret = false; do { CC_BREAK_IF(! data || dataLen <= 0);
unsigned char* unpackedData = nullptr; ssize_t unpackedLen = 0;
//detect and unzip the compress file if (ZipUtils::isCCZBuffer(data, dataLen)) { unpackedLen = ZipUtils::inflateCCZBuffer(data, dataLen, &unpackedData); } else if (ZipUtils::isGZipBuffer(data, dataLen)) { unpackedLen = ZipUtils::inflateMemory(const_cast<unsigned char*>(data), dataLen, &unpackedData); } else { // 注释掉这个分支其余代码,如果图片数据data为加密的,必须首先解密才可正常使用 // unpackedData = const_cast<unsigned char*>(data); // unpackedLen = dataLen;
// 加密key const unsigned char* key = "encrypt_key_sample"; int key_len = 18;
// 加密sign const unsigned char* sign = "encrypt_sign_sample"; int sign_len = 19;
xxtea_long len = 0; // 如果加密的数据最开始几个字节如果与签名相符,则是加密的数据 if (strncmp((const char*)data, sign, sign_len == 0) { unpackedData = xxtea_decrypt((unsigned char*)data + sign_len, (xxtea_long)dataLen - sign_len, key, (xxtea_long)key_len, &len); unpackedLen = len; } else { unpackedData = const_cast<unsigned char*>(data); unpackedLen = dataLen; } ... // 后面代码无需更改 } }
这样就可以了。
|
请发表评论