在遊戲釋出之前,最好将圖檔加密,為apk/ipa加一層保護(雖然可能沒用),涉及兩個問題:
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.
讀取加密後的圖檔
暫時沒有想到更好的辦法,隻好修改了
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 <= );
unsigned char* unpackedData = nullptr;
ssize_t unpackedLen = ;
//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 = ;
// 加密sign
const unsigned char* sign = "encrypt_sign_sample";
int sign_len = ;
xxtea_long len = ;
// 如果加密的資料最開始幾個位元組如果與簽名相符,則是加密的資料
if (strncmp((const char*)data, sign, sign_len == ) {
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;
}
... // 後面代碼無需更改
}
}
這樣就可以了。