Protect your game assets (currently Cocos2D only)

Creating a game is hard work - especially creating all the graphics and animations. Maybe you even hired somebody to draw all the stuff for you.

Did you ever realize how easy it is for somebody to steal the assets from your game?

No? Let me show you!

  • Download the game in iTunes
  • Locate the game's .ipa file using Finder or Spotlight (Mac)
  • Copy the .ipa file and rename the copy's extension to .zip
  • Extract the .zip file
  • Open the Payload folder
  • Right-click the <app-name>.app and use Show Package Contents
  • Here you go - all sounds, images, sprite sheets, etc., - are there!

We did not even have to use any fancy tools - it's just renaming a file.

Warning! Using these assets is not allowed without the permission of the copyright owner.

... well - you know that. But does that protect your precious images?

Just type sprite sheet <your favorite game> in Google and see what comes up.

And in the end - what would you do? Sue somebody in a foreign country? Forget about that.

Encrypt your assets!

I've added a new feature to TexturePacker which helps you to prevent all this from happening. It's called ContentProtection and simply encrypts the images.

Your app will still be able to decrypt the data, but somebody else is going to have a hard time getting it done.

Designing the encryption, I had the following goals in mind:

Ease of use
Enter the encryption key in TexturePacker and copy 2 files into your Cocos2D folder, add 4 lines of code - that's all.
Memory consumption
The runtime requires 4kB while decrypting the spritesheets. The file sizes stay the same.
The decryption uses nearly no time at all since only parts of the spritesheet are encrypted.
It should be hard to decrypt the data.

All of this works! Encrypting your assets is a piece of cake - it comes at nearly no effort - and does not have any impact on your game.

In theory it would be possible for somebody to extract the key from the app and write some decoder. The decoder and key are stored in your app - otherwise it would not be possible to use the assets in your game at all. But this will take knowledge, time and effort - and it is something that not every 6-year-old school boy or girl can perform. So instead of stealing your assets, it's likely that they go and find some easier prey.

Setting up TexturePacker for encryption

I assume that you already have TexturePacker running to create sprite sheets. So simply open an existing .tps file.

Download the newest TexturePacker - here you'll find a new option on the left: Content Protection. Press the "lock" icon and a new popup opens:

TexturePacker Content Protection Encryption Screenshot

You can enter your own key in the line edit - or simply create a new one by pressing Create new key.

To disable encryption use Clear / Disable.

Save as global key stores the key in TexturePacker as global - using it for decryption in the .pvr viewer and allowing you to paste it in other sprite sheets by simply pressing Use global key.

It is important that you change the file format to pvr.ccz - which is currently the only file format that supports encryption.

Press Publish spritesheet and you are done in TexturePacker.

The corresponding command in command line is --content-protection <key> where the key must be a 32-digits hex value.

Preparing your Cocos2D project for content protection

Download and copy the following 2 files inside your Cocos2D folder: libs/cocos2d/Support - replacing the 2 files that are already there:

Now set the key in your app. You can do this by placing 4 calls inside your startup sequence before the first sprite sheet is loaded. Try to distribute the calls among several files to make them harder to spot.

If your encryption key is aaaaaaaabbbbbbbbccccccccdddddddd, you have to split it into 4 parts with 8 digits each:

Each value is a 32-bit part of the whole 128-bit encryption key. It's quite hard to spot inside the app since it's simply another value passed to a function.

caw_setkey_part(0, 0xaaaaaaaa);
caw_setkey_part(1, 0xbbbbbbbb);
caw_setkey_part(2, 0xcccccccc);
caw_setkey_part(3, 0xdddddddd);

Make sure to add the following line to each file in which you use caw_setkey_part:

#import "ZipUtils.h"

If you had to change the file format, make sure to now load the .pvr.ccz file instead of whatever you used before. Also add the new files to your project.

That's it!


Protecting your game assets from content thieves is easy. Using the new ContentProtection feature can be set up in less than 5 minutes!

Apple's requirements on encryption and Content Protection

I am no lawyer & this is no legal statement! My understanding of Apple's iTunes Connect Guide and the Bureau of Industry and Security is that you don't need to get the ERN approval for your app/game if you use TexturePacker's Content Protection. The encryption is used to protect your intellectual property only and is not accessible to the user - excluding it from the regulations.

See the Bureau of Industry and Security Encryption FAQ - Question 15 (What is Note 4?):

Examples of items that are excluded from Category 5, Part 2 by Note 4 include, but are not limited to, the following:

Consumer applications. Some examples:
  • piracy and theft prevention for software or music;
  • music, movies, tunes/music, digital photos – players, recorders and organizers
  • games/gaming – devices, runtime software, HDMI and other component interfaces, development tools
Apple iTunes Export Compliance

Picture taken from a former version of iTunes Connect Developer Guide - Chapter "Submitting the App to App Review"