图片资源的加密和cocos2d-x中的解密

发布时间:2017-2-25 10:31:37 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"图片资源的加密和cocos2d-x中的解密 ",主要涉及到图片资源的加密和cocos2d-x中的解密 方面的内容,对于图片资源的加密和cocos2d-x中的解密 感兴趣的同学可以参考一下。

图片资源的加密和cocos2d-x中的解密

主要处理png图片,其他格式图片也是一样的原理。阅读前可以简略了解一下png格式图片的Data trunck。

     首先使用python脚本去掉png的PNG SIG(8 bytes) 以及末尾的PNGIEND(12 bytes)。然后图片剩余数据的每一个字节和秘钥字符串的每一个字符做不进位加(按位异或,解密的原理就是 a ^ b ^ b = a)。通过改写cpp工程里的 Image::initWithImageData(const unsigned char * data, ssize_t dataLen),来进行还原图片数据,也就是解密,过程就是对每一位加密后的数据按秘钥做异或运算还原数据,然后加上PNGSIG和PNGIEND。

加密脚本:(这个脚本会生成加密后的图片替换原始图片)

  1 # -*- coding:UTF-8 -*-  2 #该脚本用于加密png图片  3 __author__ = "ChenGuanzhou"  4   5 import os  6 import time  7 CUR_DIR = os.getcwd();  8 print("cur_dir:",CUR_DIR)  9 #CUR_DIR = 'C:\\Users\\chenguanzhou\\Desktop' 10 _KEY = 'jiaozi2013' #指定加密秘钥,英文 11 _ENCRYSIG = 'jiaozhi' 12 _PNGSIG = bytes([0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a]) 13 _PNGIEND = bytes([0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82]) 14 #获取filesig是否是png 15 def isPNGSig(bytes_8): 16     return bytes_8 == _PNGSIG 17  18 def isPNG(absPath):#判断是否是PNG图片 19     """ 20     :param absPath: 文件的绝对路径 21     :return: {Bool} 22     """ 23     isFile = os.path.isfile(absPath) 24     hasPNGSig = False 25     fileExt = os.path.splitext(absPath)[1] 26     isPngExt = (fileExt == ".png" or fileExt == ".PNG") 27     if isFile and isPngExt: 28         with open(absPath,"rb") as file: 29             hasPNGSig = isPNGSig(file.read(8)[:8]) 30     return isFile and isPngExt and hasPNGSig 31  32 def preProcessPng(pngData):#预处理图片数据 33     """ 34     剪掉png的signature(8bytes),IEND(12Bytes) 35     :param pngData: 36     :return: 37     """ 38     assert type(pngData) == bytes 39     lostHeadData = pngData[8:] 40     iendData = lostHeadData[-12:] 41     if iendData == _PNGIEND:#防止Png已经进行过外部软件的压缩,丢掉了IEND 42         return lostHeadData[:-12] 43     else: 44         return lostHeadData 45  46 def encryption(fileData,key):#加密操作 ascii占一个字节 47     """ 48     加密png数据 49     :param fileData:{bytes}预处理后的png数据 50     :param key:{str}秘钥 51     :return:{bytes}加密后的数据 52     """ 53     assert type(key) is str 54     k = bytes(key,"utf8") 55     klen= len(k) 56     kindex = 0 57     fileData = bytearray(fileData) 58     for i,v in enumerate(fileData): 59         if kindex >= klen: 60             kindex = 0 61         fileData[i] = v ^ k[kindex]#加密 62         kindex = kindex + 1 63     return bytes(_ENCRYSIG,"utf8") + fileData 64  65 #处理图片 66 def processPNG(filePath): 67     global filenum 68     fileData = None 69     with open(filePath,'rb') as file: 70         fileData = encryption(preProcessPng(file.read()),_KEY) 71     os.remove(filePath) 72     with open(filePath,'wb') as file: #覆盖新文件 73         file.write(fileData) 74     filenum = filenum + 1 75  76  77  78 def traverseDir(absDir):#遍历当前目录以及递归的子目录,找到所有的png图片 79     """ 80     :param absDir: 要遍历的路径 81     :return: None 82     """ 83     assert (os.path.isdir(absDir) and os.path.isabs(absDir)) 84     dirName = absDir 85     for fileName in os.listdir(absDir): 86         absFileName = os.path.join(dirName,fileName) 87         if os.path.isdir(absFileName):#递归查找文件夹 88             traverseDir(absFileName) 89         elif isPNG(absFileName): 90             processPNG(absFileName) 91         else: 92             pass 93  94  95 #------------------- 主函数-------------------------# 96 start_clock = time.clock() 97 filenum = 0 98 #traverseDir(os.path.join(CUR_DIR,"png2")) 99 traverseDir(CUR_DIR)100 end_clock = time.clock()101 time = (end_clock - start_clock)*1000102 print("encrypt %d Png Pictures"%filenum)103 print("use time %fms"%time)

解密的cpp文件

1.新增图片类型

 enum class Format    {        //! JPEG        JPG,        //! PNG        PNG,        //! ENCRYPTEDPNG        ENCRYPTEDPNG, //加密后的Png图片        //! TIFF        TIFF,        //! WebP        WEBP,        //! PVR        PVR,        //! ETC        ETC,        //! S3TC        S3TC,        //! ATITC        ATITC,        //! TGA        TGA,        //! Raw Data        RAW_DATA,        //! Unknown format        UNKNOWN    };

2,修改检测图片类型的Image::detectFormat

1 bool Image::isEncryptedPng(const unsigned char * data, ssize_t dataLen){2     if (dataLen <= 7 || memcmp("jiaozhi", data, 7) != 0){3         return false;4     }5     return true;6 }
 1 mage::Format Image::detectFormat(const unsigned char * data, ssize_t dataLen) 2 { 3     if (isPng(data, dataLen)) 4     { 5         return Format::PNG; 6     } 7     else if(isEncryptedPng(data,dataLen)){ 8         return Format::ENCRYPTEDPNG; 9     }10     else if (isJpg(data, dataLen))11     {12         return Format::JPG;13     }14     else if (isTiff(data, dataLen))15     {16         return Format::TIFF;17     }18     else if (isWebp(data, dataLen))19     {20         return Format::WEBP;21     }22     else if (isPvr(data, dataLen))23     {24         return Format::PVR;25     }26     else if (isEtc(data, dataLen))27     {28         return Format::ETC;29     }30     else if (isS3TC(data, dataLen))31     {32         return Format::S3TC;33     }34     else if (isATITC(data, dataLen))35     {36         return Format::ATITC;37     }38     else39     {40         return Format::UNKNOWN;41     }42 }

3.修改Image::initWithImageData,进行解密png

 1 bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen) 2 { 3     bool ret = false; 4     do 5     { 6         CC_BREAK_IF(! data || dataLen <= 0); 7          8         unsigned char* unpackedData = nullptr; 9         ssize_t unpackedLen = 0;10         11         //detect and unzip the compress file12         if (ZipUtils::isCCZBuffer(data, dataLen))13         {14             unpackedLen = ZipUtils::inflateCCZBuffer(data, dataLen, &unpackedData);15         }16         else if (ZipUtils::isGZipBuffer(data, dataLen))17         {18             unpackedLen = ZipUtils::inflateMemory(const_cast<unsigned char*>(data), dataLen, &unpackedData);19         }20         else21         {22             unpackedData = const_cast<unsigned char*>(data);23             unpackedLen = dataLen;24         }25 26         _fileType = detectFormat(unpackedData, unpackedLen);27 28         switch (_fileType)29         {30         case Format::ENCRYPTEDPNG:31         {32             unsigned char* copyData = new unsigned char[unpackedLen+13];//8+12-733             memcpy(copyData + 8, unpackedData+7, unpackedLen-7);34             deEncryptPng(&copyData, "jiaozi2013", unpackedLen + 13);35             ret = initWithPngData(copyData, unpackedLen + 13);36             delete[] copyData;37 38         }39             break;40         case Format::PNG:41             ret = initWithPngData(unpackedData, unpackedLen);42             break;43         case Format::JPG:44             ret = initWithJpgData(unpackedData, unpackedLen);45             break;46         case Format::TIFF:47             ret = initWithTiffData(unpackedData, unpackedLen);48             break;49         case Format::WEBP:50             ret = initWithWebpData(unpackedData, unpackedLen);51             break;52         case Format::PVR:53             ret = initWithPVRData(unpackedData, unpackedLen);54             break;55         case Format::ETC:56             ret = initWithETCData(unpackedData, unpackedLen);57             break;58         case Format::S3TC:59             ret = initWithS3TCData(unpackedData, unpackedLen);60             break;61         case Format::ATITC:62             ret = initWithATITCData(unpackedData, unpackedLen);63             break;64         default:65             {66                 // load and detect image format67                 tImageTGA* tgaData = tgaLoadBuffer(unpackedData, unpackedLen);68                 69                 if (tgaData != nullptr && tgaData->status == TGA_OK)70                 {71                     ret = initWithTGAData(tgaData);72                 }73                 else74                 {75                     CCLOG("cocos2d: unsupported image format!");76                 }77                 78                 free(tgaData);79                 break;80             }81         }82         83         if(unpackedData != data)84         {85             free(unpackedData);86         }87     } while (0);88     89     return ret;90 }

最后加一句:python大法好。

上一篇:Fiddler录制jmeter脚本--V4.4..0.1版本
下一篇:SpringAOP代理报错问题

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。