manulaiko / Assets-Obscurer

Easily encrypt and decrypt your game assets

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Assets Obscurer

Encrypt/decrypt the assets of your game easily.

Table of contents

Introduction

This tool encrypts the assets and renames them to their SHA-1 hash. It allows you to easily encrypt/decrypt them so you don't have to worry about them being ripped.

This tool runs in two modes: stand alone and as a library.

Stand alone

The stand alone mode runs through the command line and allows you to encrypt/decrypt the whole folder easily.

It provides two modes: command based and automagic mode.

Command based

The command based mode is enabled by default and launches a command prompt that allows you to perform the actions you want.

First of all, the application will load the specified encryption key and the assets.index which contains the indexed assets.

The first thing you would need to do is scan the folder:

Assets Obscurer v0.0.0 by Manulaiko
======================================================
Enter a command to execute ('_help' for a list of commands): scan
Loading AES key...
Checking assets...
Scanning /home/manulaiko/Programming/Java/Assets-Obscurer/assets...
Found assets/testto/test
Found assets/test
Found 2 assets!
Added 2 new entries to the index!

Then you'll either want to encrypt or decrypt the indexed assets:

Enter a command to execute ('_help' for a list of commands):  encrypt
Checking assets...
Encrypting 2 assets...
Encrypting assets/testto/test...
assets/testto/test encrypted to assets/85B310D47A7E8821216DCA09F1EB2706FF81D64D
Encrypting assets/test...
assets/test encrypted to assets/1BC9E9E4A46BF8019A624F230CBDADEEFA56E0E7
2 assets encrypted!
Updated 2 entries of the index!
Enter a command to execute ('_help' for a list of commands): decrypt
Checking assets...
Decrypting 2assets...
Decrypting assets/testto/test...
assets/85B310D47A7E8821216DCA09F1EB2706FF81D64D decrypted to assets/testto/test
Decrypting assets/test...
assets/1BC9E9E4A46BF8019A624F230CBDADEEFA56E0E7 decrypted to assets/test
2 assets decrypted!
Updated 2 entries of the index!

Once you've made your changes remember to save the new index file:

Enter a command to execute ('_help' for a list of commands): save_index
Checking assets...
Saving assets index to assets/assets.index...
Assets index updated.

You can dump the index at any moment with the dump_index command:

Enter a command to execute ('_help' for a list of commands): dump_index
assets/testto/test:
      Hash: 85B310D47A7E8821216DCA09F1EB2706FF81D64D
      Encrypted: false

assets/test:
      Hash: 1BC9E9E4A46BF8019A624F230CBDADEEFA56E0E7
      Encrypted: false

Total: 2 indexed assets.
      0 encrypted assets.
      2 decrypted assets.

If you add new assets to the folder while the application is running you just need to rescan it and the new index will be updated:

Enter a command to execute ('_help' for a list of commands): scan
Checking assets...
Scanning /home/manulaiko/Programming/Java/Assets-Obscurer/assets...
Found assets/testto/test
Found assets/new_asset
Found assets/test
Found 3 assets!
Added 1 new entries to the index!

Automagic mode

Having control on what the tool is doing is nice, but most of the times you'll either encrypt or decrypt the assets, so why not just do it automatically?

The automatic mode is executed when the command mode is disabled, so just pass -c=false as an argument and the application will automatically scan, encrypt/decrypt, save the index and dump it to the console.

By default it automatically encrypts the assets, so to make it decrypt them just pass -e=false as an argument:

$ java -jar bin/Assets-Obscurer.jar -c=false
Assets Obscurer v0.0.0 by Manulaiko
======================================================
Loading AES key...
Checking assets...
canning /home/manulaiko/Programming/Java/Assets-Obscurer/assets...
Found assets/two
Found assets/three
Found assets/one
Found 3 assets!
Added 0 new entries to the index!
Checking assets...
Encrypting 3 assets...
Encrypting assets/two...
assets/two encrypted to assets/7448D8798A4380162D4B56F9B452E2F6F9E24E7A
Encrypting assets/three...
assets/three encrypted to assets/A3DB5C13FF90A36963278C6A39E4EE3C22E2A436
Encrypting assets/one...
assets/one encrypted to assets/E5FA44F2B31C1FB553B6021E7360D07D5D91FF5E
3 assets encrypted!
Updated 3 entries of the index!
Checking assets...
Saving assets index to assets/assets.index...
Assets index updated.
assets/two:
      Hash: 7448D8798A4380162D4B56F9B452E2F6F9E24E7A
      Encrypted: true

assets/three:
      Hash: A3DB5C13FF90A36963278C6A39E4EE3C22E2A436
      Encrypted: true

assets/one:
      Hash: E5FA44F2B31C1FB553B6021E7360D07D5D91FF5E
      Encrypted: true

Total: 3 indexed assets.
      3 encrypted assets.
      0 decrypted assets.

$ java -jar bin/Assets-Obscurer.jar -c=false -e=false
Assets Obscurer v0.0.0 by Manulaiko
======================================================
Loading AES key...
Checking assets...
Scanning /home/manulaiko/Programming/Java/Assets-Obscurer/assets...
Found assets/E5FA44F2B31C1FB553B6021E7360D07D5D91FF5E
Found assets/A3DB5C13FF90A36963278C6A39E4EE3C22E2A436
Found assets/7448D8798A4380162D4B56F9B452E2F6F9E24E7A
Found 3 assets!
Added 3 new entries to the index!
Checking assets...
Decrypting 3 assets...
Decrypting assets/two...
assets/7448D8798A4380162D4B56F9B452E2F6F9E24E7A decrypted to assets/two
Decrypting assets/three...
assets/A3DB5C13FF90A36963278C6A39E4EE3C22E2A436 decrypted to assets/three
Decrypting assets/one...
assets/E5FA44F2B31C1FB553B6021E7360D07D5D91FF5E decrypted to assets/one
3 assets decrypted!
Updated 3 entries of the index!
Checking assets...
3 assets where deleted from index.
Saving assets index to assets/assets.index...
Assets index updated.
assets/two:
        Hash: 7448D8798A4380162D4B56F9B452E2F6F9E24E7A
         Encrypted: false

assets/three:
        Hash: A3DB5C13FF90A36963278C6A39E4EE3C22E2A436
        Encrypted: false

assets/one:
       Hash: E5FA44F2B31C1FB553B6021E7360D07D5D91FF5E
       Encrypted: false

Total: 3 indexed assets.
       0 encrypted assets.
       3 decrypted assets.

As a library

It's fine and good to be able to encrypt/decrypt files with a tool, but how do you implement it in your game?

First you'll need to import the sources with your project so you can use the tool directly from the code.

The first thing you'll need is to configure the com.manulaiko.assetsobscurer.main.Settings class which contains the configuration settings for the application. Most of the times you'll only have to edit Settings.assets (the path to the assets folder) and Settings.key (the path to the encryption key):

package my.game;

import com.manulaiko.assetsobscurer.main.Settings;

public class Main {
    public static void main(String[] args) {
        Settings.assets     = new File("./assets"); // default value.
        Settings.publicKey  = null;                 // default value, will generate a key pair.
        Settings.privateKey = null;                 // default value    
    }
}

After that, you can just call com.manulaiko.assetsobscurer.assets.AssetsManager.instance() and do things:

package my.game;

import com.manulaiko.assetsobscurer.main.Settings;
import com.manulaiko.assetsobscurer.assets.*;

public class Main {
    /**
     * Set `Settings.assets` and `Settings.key`.
     * Retrieve AssetsManager instance.
     * Use it.
     */
    public static void main(String[] args) {
        Settings.assets     = new File("./assets"); // default value.
        Settings.publicKey  = null;                 // default value, will generate a key pair.
        Settings.privateKey = null;                 // default value
        
        AssetsManager assets = AssetsManager.instance();
        
        Index.Asset userModel = assets.find("assets/models/user.g3db");
        Index.Asset userTexture = assets.find("assets/textures/user.png");
        
        InputStream ship = assets.asInputStream("assets/models/ship.g3db");
    }
}

Encryption

The encryption works by generating a session key, encrypting the assests with it and then encrypt the session key with a RSA key pair, this way it achieves asymmetric encryption.

The assets are encrypted, moved to the root of the folder and renamed to their hash. To keep track of them, they're added to the assets.index which is a json file like this:

{
    "assets": [
        {
        "hash": "SHA-1 hash",
        "path": "Path to the asset",
        "isEncrypted": false
        }, 
        {
        "hash": "00fd0148fdfg014fa0f8248f2kkk",
        "path": "assets/models/ship",
        "isEncrypted": true
        }
    ]
}

Of course, it's also encrypted.

By default, all assets will be encrypted with the same session key, which is generated at runtime. You can generate a different key at anytime by setting the current one to null.

You can specify the length of the key with the -l=length argument (default is 256).

In case the public key AND the private key are null, a new key pair will be generated. By checking that both keys are null, you can ship the private key with the game without worrying about your assets being modified by the users.

For example, on an online game, you would wait for the server to send the private key like this:

package my.game;

import com.manulaiko.assetsobscurer.main.EncryptionManager;
import java.security.InvalidKeyException;

public class Main {
    /**
     * Build a private key from the received command.
     * Back up the current secret key (if something goes wrong).
     * Set new private key.
     * Reinitialize assets manager.
     */
    public static void main(String[] args) {
        CommandManager.onSecretKeyCommand(command -> {
            PrivateKey old = EncryptionManager.instance().privateKey();
            
            try {
                EncodedKeySpec spec = new PKCS8EncodedKeySpec(command.bytes);
                KeyFactory factory = KeyFactory.getInstance("RSA");
                
                PrivateKey pk = factory.generatePrivate(spec);
                
                EncryptionManager.instance().privateKey(pk);
            } catch (Exception e) {
                System.out.println("Couldn't set private key!");
            }
            
            try {
                AssetsManager.instance().reinitialize();
            } catch (InvalidKeyException e) {
                System.out.println("Invalid secret key!");
                
                EncryptionManager.instance().publicKey(old);
            } catch (Exception e) {
                System.out.println("Couldn't reinitialize assets manager!");
            }
        });
    }
}

Arguments

This are the supported command line arguments:

Name Value Default Description Example
a string ./assets Sets the path to the asset folder -a=./assets
l int 256 Sets the encryption key length -l=256
c boolean true Enables the command based mode -c=true
e boolean true Automatically encrypts the assets -e=true

About

Easily encrypt and decrypt your game assets

License:MIT License


Languages

Language:Java 100.0%