Summary of Cocos2d-x resource encryption and decryption practices, cocos2d-x encryption and decryption

Source: Internet
Author: User
Tags csv parser

Summary of Cocos2d-x resource encryption and decryption practices, cocos2d-x encryption and decryption

This article is Siliphen original, reproduced please indicate the source: http://blog.csdn.net/stevenkylelee


 

This article is aimed at the cocos2d-x 3.4 version of research.


 

How to implement encryption and decryption

 

 

Brief Introduction to encryption and decryption algorithms

 

First, encryption and decryption should be a separate topic, which generally does not involve specific engines, frameworks, and technologies.

Encryption algorithms include Base64 and DES.

Base64 is similar to the Caesar password. What is the Caesar password? One character is replaced by another character.

For example, a uses I instead, B uses k instead, and so on. The encryption and decryption process is a ing process.

DES is an encryption algorithm that uses keys.

The difference between the keyless algorithms DES and Base64 is:

The DES algorithm itself can be kept confidential. As long as the key is kept confidential, the key is the key to decryption.

If Base64 is used for encryption, the algorithm itself is the key. To keep algorithms confidential.

 

MD5 and SHA are digest algorithms.

Base64 and DES can both restore the ciphertext to the plaintext.

While MD5 and SHA cannot restore the original data after the algorithm is applied.

Digest algorithms are generally used for identity authentication.

 

To Encrypt resources, we need to select an algorithm that can restore the ciphertext to the plaintext.

 

Design your own encryption and decryption algorithms

 

This is part of cryptography.

You can map the content of each byte to encrypt the content based on the principle of the Caesar password.

You can also encrypt 1-byte, 2-byte, and 4-byte data using a certain number of exclusive or operations.

The unique or characteristic is that, using number A to compare content B or obtain content C, then using number A to compare content C or obtain content B.

This feature can be used for encryption. At the same time, number A serves as the key.

 

Different encryption algorithms are designed with different interfaces.

If the preceding two methods are used for encryption algorithms, the encryption algorithm can be implemented in place,

It can be decrypted directly in the memory where the ciphertext is located, and the decrypted data can be stored without separately allocating memory.

If the encryption algorithm is complex and cannot be restored locally, you need to apply for a new memory to save and decrypt the data.

Of course, the execution speed is generally "Local restoration.


I think it is best to design your own encryption algorithm if you can.

Keys are the key to using algorithms such as existing DES.

If you design an algorithm that uses key encryption, the key and algorithm are not disclosed.

To obtain the resource plaintext, take the following steps:

1. Find the key constant in the program.

2. Read and decompress the Assembly to restore the algorithm, or find a way to use the assembly code of the encryption algorithm.

Step 2 will increase the difficulty of decryption by the decryptor. This is the advantage of self-designed encryption algorithms over well-known algorithms such as existing DES.


 

Application mechanism of encryption and decryption

 

I have seen some people encrypt the field content.

For example, if he saves data in xml, he only encrypts the stored values.

The content is similar to this: <Entity Hp = "ciphertext" AttackValue = "ciphertext">

This is not a good way to use encryption, because this method will:

1. disclose the configuration file structure of the program. XML, json, etc.

2. revealed the data structures that may be used by the program. Based on the above content, we can guess that the Entity class has two fields: Hp (blood volume) and AttackValue (attack power)

 

A more thorough encryption method is to encrypt the entire xml, json, and other files.

In this way, others will not know a little bit about your data.

This method does not directly use the LoadFile-like function encapsulated by the data parsing database to directly read files.

Instead, read the encrypted file into the memory using the file reading method, decrypt the data in the memory, and then pass the decrypted data to the parsing function of the database.

This method requires that the database has an interface for memory parsing.

For example, if you use XML to Parse the database, the LoadFile is discarded and the Parse method is required.

 

In one case, you may not be able to encrypt the entire data file.

When using databases such as sqlite, fields can only be encrypted at this time.

 

Some people design encryption mechanisms that require the configuration program itself.

For example, a program requires a configuration (a switch variable or Conditional compilation) to determine whether to decrypt the resource.

When the product is released, the resources are encrypted and the program is enabled to decrypt the resources.

During development, the resource does not need to be encrypted, and the program is blocked from decrypting the resource.

This method requires setting the decryption switch back and forth, which is cumbersome.

 

One idea is more scalable, more flexible, and more convenient to use.

That is, design your own file header.

People familiar with Win32 programming may know the PE file format.

Before Windows runs an exe, it will check the PE file header,

After obtaining information such as the Data constants and code blocks of the EXE file, the system can correctly execute an EXE file.

We can design an encrypted file header with a field in it to identify whether the file is encrypted.

The decryption algorithm determines whether to decrypt and which decryption algorithm is used by determining the identifier of the encryption header.

 

This is a data-driven decryption mechanism that stores decrypted information in the encrypted data itself.

For unencrypted data, the program will not perform decryption if it determines that there is no file encryption header identifier.

In this way, the program can read unencrypted data and encrypted data at the same time without any modifications to the program.

 

Note: The identifier of the encryption header should be special enough to ensure that there is no conflict with unencrypted data.

If the unencrypted data contains the encrypted header, the program decrypts the unencrypted data.

 

 

Research Process of encryption and decryption in Cocos2d-x

 

 

My project configuration uses CSV files. The parser uses a CSV parser written by myself:

Implementation of CSV file format parser: from string Split to FSM

In the game, this part of decryption is easy to implement, that is, to encrypt the entire file,

When the game starts, it reads the encrypted file into the memory for decryption, and then transmits the decryption data to the parser for parsing.

 

Some game-generated data that needs to be saved. I use XML to save the data. The encryption and decryption ideas are also described above.

 

However, for images, animations, particles, and the UI exported from cocostudio1.6, encryption is not that easy.

Because interfaces like Sprite: create do not provide a way to get texture data from memory to initialize the genie,

Instead, it reads data directly from the disk file. Users cannot interfere with reading and loading file data externally.

 

How to encrypt game resources? -- Only the engine is modified. --!

I think modifying the engine is not a good practice.

The engine should be maintained by the engine provider, rather than by the user.

It is difficult for the user to manually upgrade the project.

Changing the engine to a new version is troublesome.

Even if the engine version is changed a bit, it is very troublesome to make a modification once.

 

To modify the engine, you must first track and debug the engine,

With cocos2d-x 3.4 as the test version, from Sprite: create entry, step by step,

See where the engine loads file data.

After debugging tracing, the Sprite: create call stack is as follows:

GetData

FileUtilsWin32: getDataFromFile

Image: initWithImageFile

TextureCache: addImage

Sprite: initWithFile

Sprite: create


In windows, when the genie loads images, it calls

CCFileUtils-win32.cpp in this file

Static Data getData (const std: string & filename, bool forString) function.

This function is a non-class member static function.

 

Debug other data loading. The call stack of the cocostudio1.6 animation is:

Cocos2d: FileUtilsWin32: getFileData
Cocostudio: DataReaderHelper: addDataFromFile
Cocostudio: ArmatureDataManager: addArmatureFileInfo


After tracking and debugging of various file types, We can summarize,

Basically there are 2 load functions for the file, all in the CCFileUtils-win32.cpp file,

1. FileUtilsWin32: getFileData

2. getData

 

To decrypt the two functions, modify them.

It is worth noting that the signature of the getData function is:

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

The forString parameter is used to identify whether the read file is a text file.

 

If forString is true, the buffer must allocate one more byte to store the string Terminator \ 0 of the C language.

The following engine code:

 

 


To decrypt the data, we also need to use forString to determine whether to allocate one byte of memory.

 

FileUtils single-piece class. Many functions are virtual functions. FileUtils: getInstance,

On Windows, the returned FileUtilsWin32 subclass object.

On the Android platform, the FileUtilsAndroid subclass object is returned.

Cocos2d-x 3.4 implements decryption on Windows and Android platforms need to modify 2 files:

For Windows: cocos \ platform \ win32 \ CCFileUtils-win32.cpp

Android platform: cocos \ platform \ android \ CCFileUtils-android.cpp

The two files contain the getData and getFileData functions, which must be modified.

 

Reading file data is implemented on different platforms,

If you want to encrypt resources on the target platform, you need to modify the read implementation on the target platform.

FileUtils is a base class for reading files and provides default implementations. Some platforms provide specific implementations.

Through polymorphism, FileUtils makes it unnecessary for our game client code to perform specific processing on a specific platform,

You do not need to care about the type of the FileUtils subclass.


Unfortunately, due to the time relationship, I have not found a method to decrypt the audio file.

Debugging tracking found that the Cocos2d-x played audio on Windows directly called Win32 APIs that input a file path to play the audio.

As mentioned earlier, encryption and decryption require the application data interface to retrieve data from the memory.

The interface can directly read disk files, so there is no way to intervene in file loading for data decryption.


I think the engine designer can provide an interface that uses the observer mode,

Engine users can intervene in Data Reading and performing data conversion without modifying the engine itself to achieve decryption.

After all, changing the engine is not a good practice.

 

 

Supported encryption and decryption tools

 

 

Generally, we need to encrypt resource data and do two things:

1. Write a tool to encrypt disk files. This tool may need to traverse folders and select files in batches.

2. Add the decryption function to the software program to decrypt the encrypted data of the tool.

 

Tools are very important to facilitate operations and improve productivity.

 

Here, I made two tools myself.

1. cocos2d-x engine modification and recovery tools, so that it has decryption function. As follows:

 

 

 

2. encryption and decryption tools for disk files to facilitate batch filtering during packaging. As follows:

 


This tool can identify whether the file has been encrypted. The principle is to use the "Encrypted File Header" design described earlier.

This prevents re-encryption of encrypted files and decryption of unencrypted files.

Reduces the possibility of misoperations and intuitively displays the encryption status of the file.

Without an encrypted file header, the tool program cannot identify whether a file has been encrypted.



Additional encryption/Decryption overhead



Resource encryption Reduces Program performance. The reason is simple. You need to process file data in an additional way.

For a slightly more complex encryption algorithm, you may need to apply for memory space to save and decrypt data. Delete and new are all time-consuming operations.


Resource encryption may also increase the size of the apk package. Why?

The reason is that, with Cocos2d-x development, resources will have a lot of *. plist *. ExportJson *. tmx and other files.

Plist may be a configuration or particle.

*. ExportJson and other files are animation and UI export files made by Cocostudio1.6.

*. Tmx is the map format output by Tilemap.

All the files mentioned above are stored in text. You can use Windows notepad to open and view the content.


The apk package is actually a compressed package. The compression algorithm has a high compression rate for files with a large amount of redundant data.

I have previously written an article about compression algorithms, File compression and decompression: user-friendly coding.

I have done a test. After the UI *. plist *. ExportJson file of more than 600 KB is packaged into an apk package, it actually only occupies more than 60 KB.

This is because the compression algorithm has a high compression ratio for these configured text files.


If our encryption algorithm reduces redundancy data.

For example, the content of a file is "111111...", 0.1 million 1.

To increase security, our encryption algorithm encrypts the content into "sfsadfsa ....".

It is difficult for the decryptor to introduce the original "111111..." content from irregular, non-repetitive data,

But at the same time, the compression ratio of such data will be very low.


I have previously designed an algorithm that uses key encryption to eliminate redundant data,

For content with the same character, it can be encrypted into a seemingly irregular mess of content,

In fact, there are still rules, but there are a lot of irregular loops.

Then, the encrypted data cannot be compressed.

The size of the exported apk package after the encrypted resource is much larger than that of the unencrypted resource package.


In this case, you can only encrypt images and other key resources, rather than non-critical text files.

Or reduce the encryption strength of the algorithm and retain data redundancy.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.