views:

174

answers:

6

So I am working on a java application, and the customer has requested the ability to have features that which can be unlocked to make the application customizable based upon what their customer wants to pay for. So I am trying to come with ideas for doing this in a manner that will provide some level of security, but also general maintainability and readability.

I have been doing some searching around, and had some ideas of my own, maintaining an encrypted configuration file which could possibly be stored in a jar file that I could unload, repack, and load at run time.

Looking to see if anyone else has any interesting ideas on how you might do this. I have been doing some looking on google without a lot of success thus far.

Oh one last little caveat, the machines this java application is on may not have internet available to them. So running a license server doesn't seem like a viable option

+1  A: 

The only sure way to prevent "unauthorized access" to features that are "locked" in software is not to provide the code that one does not want the user to have access to in the first place.

Enabling extra features by unlocking using passwords, encryption (where's the key going to be? In the program itself?), configuration file can usually be defeated by someone who is determined to get to the code they want to execute.

At least unlocking using software means can most likely be defeated, if the code that is locked is already being distributed in the binary. One way that I can think of off the top of my head that seems a little secure is an hardware key dongle, or having important code that is stored on hardware, but not many people like the idea of having to plug in a piece of hardware to use the software.

When it really comes down to it, don't have features in the code itself which is only disabled by some software flags.

coobird
My comment to Brian above addresses this a bit. Not looking for a an absolutely completely secure system here. I realize that they can unjar the system and do what they want, but that isn't a huge concern with the customer base in question. Want to make it "just difficult enough" to discourage simple measures. But also relatively robust.
Matt
A: 

I suggest you build a trusting relationship with your customers. Either that, or bundle a USB key dongle, but even these are not 100%.

If you are distributing software, any kind of encryption must be able to decrypt itself. You are essentially giving the customer both the lock and the key.

brianegge
There is a relative level of trust already. There are multiple versions of the application currently, which are really separated by their launching class, using different mains to load strategy sets. We know it is vulnerable to being unjarred. But in the particular customer base they have they consider the likelihood small enough that they aren't particularly worried about it. Want to make it "just difficult enough" so to speak.
Matt
A: 

You could possibly implement the core product, and then have the additional features as plugins. You could put each plugin in a separate jar file. The customer could then distribute a bundle that contained the core application, and the purchased plugins. Thus the un-purchased functionality is not in any of the binaries.

broschb
+3  A: 

I would suggest using some sort of dependency injection or runtime weaving aspects, so you can include new jar files that have the correct xml files or configuration files for new features.

I agree with coobird that including them and locking them is inherently risky as someone will eventually decompile your application and determine how to get all the features.

James Black
Definitely a different approach and something worth looking at. I know it doesn't stop someone from going into the jar, but that is a level of risk the client is willing to live with for this particular project.
Matt
They can go into the jar, but it only has the parts they paid for, so who cares.
James Black
A: 

Distribute the full set. Have them call you for the keys to unlock various features. (Use a simple encryption scheme so that the keys are of reasonable length and can be conveyed over the phone.)

A: 

Hi Matt, I've written a Java based license manager, called Padlock which meets your needs (http://www.javalicensemanager.com). Specifically, it uses file based licenses which are cryptographically signed using RSA. The public key gets embedded in your code, and the private key remains your secret. It's quite secure, with the only known method of attack being code decompliation.

The licenses support unlimited feature keys, so you'd be able to specify any number of features in the license, with your code triggering functionality based on the feature keys in the license file. If end user wants to enable a new feature, he would simply need a new license file that has this feature enabled. On startup, your app would read the license file and unlock functionality as appropriate.

The value in Padlock is that it takes care of the areas of pain with licenses: The license validation routine you call ensures that the file hasn't been modified (integrity), that it was signed by you (authenticity), and that the current date is within the license date parameters (start date, expiration date). The newest version (2.0) which is in public beta also support hardware locked licenses (via the MAC address).

The Padlock website contains a usage and integration guide, feel free visit the website and email me with any questions.

Thanks, Jason

Jason Nichols