【加密】Cocos2d-x PNG图片资源加密修改版

【说明】

这篇文章是对上一篇【Cocos2d-x PNG图片资源加密】的补充和扩展,那篇文章转自【旧时尘安】博客,文中已经对原理和使用讲解的很清晰,这里只是根据我自己的使用情况做一些小小的功能扩展,也是自己做个整理,以便日后使用。如有侵权,请联系删除


链接

原文地址:http://www.cnblogs.com/zhangpanyi/p/4560297.html

原始工程:https://github.com/zhangpanyi/EncryptPNG

【使用】

修改后的使用有所调整,原文的使用更简洁,这里主要是依照我个人的习惯作出的调整。我在代码添加了设置密钥和扩展名的接口。

1. 在cocos目录下新建文件夹 ext ,将 CCAES.cpp、CCAES.h、CCDecryptimage.cpp、CCDecryptimage.h 拷贝到其中。

2. 在Xcode项目中引用 ext 目录。

注:这里可能会报错,为此我耽误了半天,结果居然是Xcode没有自动引用导致的,我已记录到【这里】

3.Android项目需要修改 cocos/Android.mk 文件,将两个cpp文件添加进去即可。

4. 在 CCImage 中调用解密代码方法与原文一样,这里略有修改代码见附录。

注:我将对 CCDecryptimage.h 的引用放在了 CCImage.h ,是为了在项目中设置密钥时不需要再引用此头文件

5. 在项目中设置密钥和扩展名,我是在 AppDelegate.cpp 中设置。

注:如果修改扩展名,需要加密端也做修改,保证两边扩展名一致。

  1. //设置密钥
  2. constext::aes_keykey={0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
  3. ext::DecryptimageConfig(key,".epng");

代码

copy

    CCImage.cpp

copy
    boolImage::initWithImageFile(conststd::string&path)
  1. {
  2. ......
  3. if(!data.isNull())
  4. //图片文件解密
  5. if(ext::AnalyzeExtension(path)[1]==ext::TARGET_EXTENSION)
  6. {
  7. autoimage_data=ext::Decryptimage(path,data);
  8. ret=initWithImageData(&image_data[0],image_data.size());
  9. }
  10. else
  11. ret=initWithImageData(data.getBytes(),data.getSize());
  12. }
  13. #endif//EMSCRIPTEN
  14. returnret;
  15. boolImage::initWithImageFileThreadSafe(conststd::string&fullpath)
  16. if(ext::AnalyzeExtension(fullpath)[1]==ext::TARGET_EXTENSION)
  17. autoimage_data=ext::Decryptimage(fullpath,153); font-weight:bold; background-color:inherit">returnret;
  18. }

copy

    <spanstyle="font-family:Arial,sans-serif;">CCDecryptimage.h</span>

copy

    #ifndef__CC_DECRYPT_IMAGE_H__
  1. #define__CC_DECRYPT_IMAGE_H__
  2. #include<array>
  3. #include<vector>
  4. #include"CCData.h"
  5. #include"CCAES.h"
  6. namespaceext
  7. /*解密扩展名*/
  8. staticstd::stringTARGET_EXTENSION=".epng";
  9. /*解密密钥*/
  10. staticaes_keySECRET_KEY={0x31,0x39};
  11. /**
  12. *设置解密秘钥
  13. *@paramkey秘钥(AES的16位秘钥)
  14. *@paramexten文件扩展名(需要解密的文件扩展名,如".png")
  15. */
  16. voidDecryptimageConfig(constaes_key&key,conststd::string&exten=TARGET_EXTENSION);
  17. /**
  18. *解密图片文件(在CCImage中调用
  19. *@paramfilename文件名称
  20. *@paramdata文件数据
  21. */
  22. std::vector<unsignedchar>Decryptimage(conststd::string&filename,cocos2d::Data&data);
  23. *分解文件名的扩展名(在CCImage中调用
  24. *@paramfile_path文件
  25. std::array<std::string,2>AnalyzeExtension(conststd::string&file_path);
  26. #endif

copy

    CCDecryptimage.cpp
copy
    #include"CCDecryptimage.h"
  1. #include<sstream>
  2. #include"ccMacros.h"
  3. #if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
  4. #include<WinSock.h>
  5. #pragmacomment(lib,"ws2_32.lib")
  6. #elif(CC_TARGET_PLATFORM==CC_PLATFORM_IOS||CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)
  7. #include<netinet/in.h>
  8. #endif
  9. /*CRC码长度*/
  10. staticconstuint32_tCRC_SIZE=4;
  11. /*文件头部*/
  12. constunsignedcharHEAD_DATA[]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a};
  13. /*IENDCRC码*/
  14. charIEND_DATA[]={0xae,0x42,0x60,0x82};
  15. /*数据块头部(用于验证解密是否成功)*/
  16. charBLOCK_HEAD[]={0x45,0x6e,0x63,0x72,0x79,0x70,0x74,0x47};
  17. #pragmapack(push,1)
  18. structBlock
  19. charname[4];
  20. uint32_tpos;
  21. uint32_tsize;
  22. };
  23. structIHDRBlock
  24. Blockblock;
  25. chardata[13+CRC_SIZE];
  26. #pragmapack(pop)
  27. /*解析文件扩展名*/
  28. conststd::string&file_path)
  29. std::string::size_typepos=file_path.rfind('.');
  30. std::array<std::string,2>text;
  31. if(std::string::npos!=pos)
  32. text[1]=file_path.substr(pos);
  33. text[0]=file_path.substr(0,pos);
  34. else
  35. text[0]=file_path;
  36. returntext;
  37. template<int_Value,153); font-weight:bold; background-color:inherit">typename_Stream>
  38. std::array<char,_Value>ReadSome(_Stream&stream)
  39. ottom:none; border-left:3px solid rgb(108,_Value>buffer;
  40. for(unsignedinti=0;i<_Value;++i)buffer[i]=stream.get();
  41. returnbuffer;
  42. /*解密块*/
  43. voidDecryptBlock(std::stringstream&ss,153); font-weight:bold; background-color:inherit">constaes_key&key)
  44. conststd::streamoffcontents_size=ss.tellp()-ss.tellg();
  45. constuint32_tblock_size=(uint32_t)(contents_size+AES_BLOCK_SIZE-contents_size%AES_BLOCK_SIZE);
  46. std::vector<uint8_t>buffer;
  47. buffer.resize(block_size);
  48. for(uint32_ti=0;i<contents_size;++i)buffer[i]=ss.get();
  49. AES::DecryptData(&buffer[0],block_size,key);
  50. ss.seekg(0);ss.seekp(0);
  51. for(uint32_ti=0;i<block_size;++i)ss.put(buffer[i]);
  52. /*解密图片文件*/
  53. ottom:none; border-left:3px solid rgb(108,cocos2d::Data&data)
  54. CCAssert(!data.isNull(),"dataisnull!");
  55. //获取数据块信息位置
  56. constuint32_tblock_start_pos=ntohl(*reinterpret_cast<uint32_t*>(data.getBytes()+data.getSize()-sizeof(uint32_t)));
  57. //获取数据块信息
  58. std::stringstreamblock_info;
  59. for(uint32_ti=block_start_pos;i<data.getSize()-sizeof(uint32_t);++i)
  60. block_info.put(*(data.getBytes()+i));
  61. //解密数据块信息
  62. DecryptBlock(block_info,SECRET_KEY);
  63. //验证数据块信息是否解密成功
  64. autoblock_head=ReadSome<sizeof(BLOCK_HEAD)>(block_info);
  65. inti=0;i<block_head.size();++i)
  66. if(block_head[i]!=BLOCK_HEAD[i])
  67. CCAssert(false,"thekeyiswrong!");
  68. //写入文件头信息
  69. char>image_data;
  70. image_data.reserve(data.getSize());
  71. for(autoch:HEAD_DATA)image_data.push_back(ch);
  72. //写入数据块信息
  73. while(true)
  74. memcpy(&block,&(ReadSome<sizeof(Block)>(block_info)[0]),153); font-weight:bold; background-color:inherit">sizeof(Block));
  75. if(block_info.eof())
  76. ottom:none; border-left:3px solid rgb(108,"");
  77. cclOG("the%sfileformaterror!",filename.c_str());
  78. //写入数据块长度和名称
  79. charsize_buffer[sizeof(block.size)];
  80. memcpy(size_buffer,&block.size,sizeof(size_buffer));
  81. for(autoch:size_buffer)image_data.push_back(ch);
  82. for(autoch:block.name)image_data.push_back(ch);
  83. block.pos=ntohl(block.pos);
  84. block.size=ntohl(block.size);
  85. charblock_name[sizeof(block.name)+1]={0};
  86. memcpy(block_name,block.name,153); font-weight:bold; background-color:inherit">sizeof(block.name));
  87. if(strcmp(block_name,"IHDR")==0)
  88. IHDRBlockihdr;
  89. memcpy(&ihdr,&block,153); font-weight:bold; background-color:inherit">sizeof(Block));
  90. memcpy(((char*)&ihdr)+sizeof(Block),&ReadSome<sizeof(IHDRBlock)-sizeof(Block)>(block_info)[0],153); font-weight:bold; background-color:inherit">for(autoch:ihdr.data)image_data.push_back(ch);
  91. else"IEND")==0)
  92. for(autoch:IEND_DATA)image_data.push_back(ch);
  93. cclOG("decrypt%ssuccess!",153); font-weight:bold; background-color:inherit">break;
  94. for(uint32_ti=0;i<block.size+CRC_SIZE;++i)
  95. image_data.push_back(*(data.getBytes()+block.pos+i));
  96. returnimage_data;
  97. /*配置解密秘钥和扩展名*/
  98. conststd::string&exten)
  99. SECRET_KEY=key;
  100. TARGET_EXTENSION=exten;
  101. }

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...