I have this java swing application that I intend to sell over the internet. At the moment I'm leaning towards deploying the application using java webstart. The product will be licensed for the user to use the program on one computer at a time only. I am concerned about piracy with this model. I would like to install some security features to enforce the license model. The goal is to at least make it difficult for a licensed user to copy the installed product including license key to unlicensed users. Here are the options I am looking at now:
Force the user to authenticate to the mother ship with a username/password each time the program is launched.
Simply install a license key somewhere (hidden?) on the users PC after they have registered and paid. At runtime, verify that there is a valid license key installed.
Use/build a security package that is based on a hardware fingerprint of the users computer. This fingerprint would be computed each time the app is started and compared with the locally installed license key using some sort of hash. This license key would be would only be valid with this hardware fingerprint.
One of the issues here is that once this application is installed, there isn't any runtime need for the application to contact the mother ship, other than checking for application updates using java webstart. Everything the app does it does locally and displays the results to the user using swing. So any solution involving a mother ship would basically mean building a server infrastructure for the sole purpose of license verification.
I guess what I'm looking for is something java based that is at least somewhat secure, easy to deploy and is not a pain for the user. What security/licensing approach have you used?
EDIT: I should add that I am not necessarily looking for a silver bullet to prevent absolutely everyone from defeating security. There will always be someone with enough time on their hands to find ways to get it done. I'm not so concerned with these guys. I'm basically looking to make it difficult for a casual user to simply copy the license key and send to his buddies. Implemented correctly, the solution should convince the casual user that it is simpler to just buy it.
Consider using JNLP to have a time limited component in your application - the license module? - which must be regularily updated over the internet. The accessability to the updated version requires registration. Let the
Have a long grace period allowing the user to be offline (or not wanting to upgrade) for a period before disabling functionality.
I'd say (2) is your best bet. You've already talked yourself out of (1), and (3) would cause problems if the user, say, bought a new motherboard. (2) won't be much protection against a reasonably computer-savvy user, but it shouldn't cause too many problems either.
But in the end, nothing you can do will stop a determined user from pirating your software.
-- Jeff Atwood
My best bet, implement an easy solution that doesn't tax you too much, and that doesn't make the customers irate, to discourage the occasional piracy. Anything more complicated and it will be an arms-race. One that is too difficult to win.
I'd seriously reconsider the licensing requirements, because enforcing them will lose you legitimate customers. If you're a huge company, you can afford that, but if you're a startup or an individual you can't.
One way out is to offer an individual license - good for all machines the individual uses. This, for better or for worse, is how people think software "should" be sold. If you make them pay for each machine they use they'll feel like you're taking advantage, and that's when they start trolling the web for someone else's license key.
If appropriate, you could also offer a corporate license, or 10-packs of licenses, or whatever, for a discount over buying them separately. This gives both individuals and organizations ways to use your software legally that don't make them feel like you're squeezing them unreasonably.
Of your three solutions:
The first requires a net connection to do anything. Users are not going to be happy if they can't use it offline. Google had to deal with that for its office software.
The second isn't much copy protection, unless the location is hidden, and a hidden location has its own difficulties (some people, for example, dislike installing apps that like to hide things in various locations), and isn't secure anyway.
The third will likely work until a user does something to a computer that changes the fingerprint (I don't know what you'd be checking), or wants to move the app from one computer to a replacement. Then you'll have a potentially irate user. ("I replaced the hard drive/moved to a different LAN connection/had a system failure/whatever, and the [expletive deleted] thing just stopped working!")
So, while number 2 won't likely cause a user problems, it won't work for much of a copy protection scheme. Numbers 1 and 3 are going to get you unhappy users, will be a certain amount of trouble for you, and won't stop determined people from copying it anyway.
Unless the application already needs to connect to the net to do it's actual work, phoning home might easily be classified as spyware.
And I am not sure if this applies to Java Web Start, but as firewalls may block your application from phoning home, your paying customers may still see their application blocked.
So: I would not use something that phones home every now and then.
(As for license keys: if a key only works with a specific registration name, and if that name is shown in some About dialog, then I would not worry about making it hardware dependent. Sure, a few registration names and their keys will be shared, but anything more fancy is not worth the effort. If my Mac fails me then I would not be amused to see my 1-click Time Machine restore on new hardware make your application fail to start.)