jGAF provides three basic layers of API to project your Java application, if needed:

  • user name and license key protection
  • library sealed with an expiration date
  • string obfuscation mechanism

Let's discover how to use these APIs.

Java Application Protection Packages

jGAF Protection API is contained in two packages :

  • com.plealog.genericapp.protection.distrib: contains Protection API that has to be used by your software to apply protection(s)
  • com.plealog.genericapp.protection.local: contains Protection manager API and utilities that DO NOT have to be distributed with your software

Note: the provided "build.xml" Ant project file (target "package") is configured to appropriately discard package "protection.local" from the "jgaf.jar" binary file.

Protecting your application with a license key

Creating a license key

The license key is generated using a token. Usually, this token is the user name or the email of your customer.

To illustrate how to create that license key from a token, you can have a look at a utililty tool called LicenseKeyGenerator provided within the "com.plealog.genericapp.protection.distrib" package. As you can see, the API is very straightforward:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.plealog.genericapp.protection.local;
 
import com.plealog.genericapp.protection.distrib.LicenseKeyController;
 
public class LicenseKeyGenerator {
  /**
   * Utility takes a single argument: user token
   */
  public static void main(String[] args) {
    System.out.println("User name: ["+args[0]+"]");
    System.out.println("License  : "+LicenseKeyController.generate(args[0]));
  }
  //Example using myself as args[0] of the utility tool:
  //Patrick Durand: L8P78-A5RL7-J4YP2-F3BBZ-7W57Y
}

 

Of course, you can pass to LicenseKeyController.generate(String token) any string you want: user name, user email, both values, etc. But then, you'll have to reuse exactly the same token to unlock your application. Let's see how to do that.

Using a license key to unlock your application

Here is a sample code illustrating how to check whether or not your application (protected using jGAF Protection API, of course) can execute... or not:

Step 1: somewhere in your application, you initialize your application with user token and license key, as follows:

1
2
3
4
import com.plealog.genericapp.api.protection.ControllerModel;
 
// Setup the Controller
ControllerModel.setLicenseKeyProtectorModel(String licenseKey, String userName);

 

In the above code snippet, licenseKey and userName are exactly the values from: licenseKey = LicenseKeyController.generate(userName).

Step 2: somewhere else in your application, you check that the Controller is valid:

1
2
3
4
import com.plealog.genericapp.api.protection.Controller;
 
//test this: if it returns true, your application should not continue execution!
Controller.getProtector().isLibraryInvalid();


Real application recipes

Generating a license key is always done on "your side". For instance, it can be done using your home-made license manager system, that uses the jGAF Protection API. It can also be included within license key generation system available on some App Stores. For instance, I did use such a mechanism using the ShareIT/Digital River eBusiness platform: when a customer bought a software, the ShareIT platform executed a piece of code of mine, relying on my Protection API, to create a license key from the user email address, then all that information was sent to the customer by email, in a fully automated way.

In real application, you run above mentioned "Step 1" using a dialogue box: it asks the user to enter userName and LicenseKey, and when he/she closes the dialogue box, provided values are transfered to class ControllerModel. Then, it's up to you to call Controller.getProtector.isLibraryInvalid() in various places (at least once) of your software. These values can also be made persistent using the jGAF Persistence API, avoiding the user to enter his/her credentials each time your application is started.


Protecting your application with an expiration date

While the above protection mechanism is done at runtime, the protection by expiration date is done at build time: when you prepare the packaging of your application, you will include the expiration date. Then it will be used to check whether or not your application is still valid.

What is the practical use case of that expiration date? For instance, you can use it when providing evaluation versions of your application.

How does it work?

The following design is used to protect your application with an expiration date:

  • a template class is copied to a "real" Java class and it is updated with the protection time stamp
  • that real class is part of your distributed software and can be used to validate or not its execution

It is worth noting that the template class is part of the com.plealog.genericapp.protection.local package, whereas the real time-stamped class is part of the com.plealog.genericapp.protection.distrib package; as stated earlier, the former package is NOT shipped with your application, whereas the latter DOES.

Step1: preparation the time-stamped class

This is easily done using the utility class called LibraryDateProtectorGenerator (package com.plealog.genericapp.protection.local) that takes three arguments:

  • path to the template class; always use /absolute/path/to/com/plealog/genericapp/protection/local/LibraryDateProtectorController.template
  • path to the time stamped class that is going to be created; always use always use /absolute/path/to/com/plealog/genericapp/protection/local/LibraryDateProtectorController.java
  • number of days during which the library will be valid (reference date is today);

LibraryDateProtectorGenerator will create a new class LibraryDateProtectorController.java within package com.plealog.genericapp.protection.distrib that "hard" contains a date which is "today's date + number of days". It means the following: if "number of valid days" is 90 (third argument of LibraryDateProtectorGenerator) and you execute LibraryDateProtectorGenerator on February 1st, 2016, then class LibraryDateProtectorController.java contains an expiration date equals to May 1st, 2016. So, the latter date is really hard contained into your software; event if a user installs your application on April 14th, 2016, it will stop working on May 2nd, 2016. This is the reason why this "expiration date" (as it is provided with jGAF) is a build time protection system.

Step 2: package your updated jGAF library

From the command-line, enter the home directory of jGAF source code, then run:

ant package

This will create a jgaf-x.y.jar containing the time stamp: a date beyond which your application will fail to execute.

Step 3: update your application code

Use the jgaf-x.y.jar created at step 2 in your application build path. Then add the following code control somewhere in your application (e.g. at startup time):

1
2
3
4
import com.plealog.genericapp.api.protection.Controller;
 
//test this: if it returns true, your application should not continue execution!
Controller.getProtector().isLibraryExpired();

 

Protecting your strings with obfuscation

You can easily convert plain text into an obfuscated version using the utility class: ObfuscateStringGenerator, located in package com.plealog.genericapp.protection.local.

For instance, using the String Obfuscator API available in jGAF let you replace:

1
public String libName = "GenericApp Library";


by:

1
2
public String libName = new HStringCoder("2RuVXZpJ0YwFCcMBWayJXY5J").toString() 
   /* => GenericApp Library */;

 

This way, plain texts replaced by obfuscated representations makes reverse engineering of your application more difficult.

Obfuscating the jGAF library

jGAF Java archive file (jgaf-x.y.jar) can be fully obfuscated using tools such as YGuard. Actually, have a look at the "build.xml" Ant project file provided with jGAF source code: there is a commented out target called "mask" that shows how this can be achieved. Of course, adapt the obfuscation procedure to the needs of your software.